Open TheLoneWolfling opened 5 years ago
Backtrace with locals (from GDB):
#4 in lfs_bd_prog (lfs=0x555555761120 <lfs>, pcache=0x555555761138 <lfs+24>, rcache=0x555555761120 <lfs>, validate=false, block=0,
off=94, buffer=0x7fffffffde04, size=4) at lfs.c:223
data = 0x7fffffffde04 "\360\017\364\004\001"
__PRETTY_FUNCTION__ = "lfs_bd_prog"
#5 in lfs_dir_commitprog (lfs=0x555555761120 <lfs>, commit=0x7fffffffdf90, buffer=0x7fffffffde04, size=4) at lfs.c:1181
err = -267389948
#6 in lfs_dir_commitattr (lfs=0x555555761120 <lfs>, commit=0x7fffffffdf90, tag=537921536, buffer=0x555555774210) at lfs.c:1204
dsize = 4
ntag = 83103728
err = 0
#7 in lfs_dir_commit_commit (p=0x7fffffffdfd0, tag=537921536, buffer=0x555555774210) at lfs.c:1406
commit = 0x7fffffffdfd0
#8 in lfs_dir_traverse (lfs=0x555555761120 <lfs>, dir=0x7fffffffe0ec, off=94, ptag=3491757060, attrs=0x7fffffffe070, attrcount=1,
hasseenmove=false, tmask=0, ttag=0, begin=0, end=0, diff=0, cb=0x5555555584be <lfs_dir_commit_commit>, data=0x7fffffffdfd0) at lfs.c:751
err = 0
tag = 537921536
buffer = 0x555555774210
disk = {block = 4294958848, off = 32767}
mask = 2146435072
#9 in lfs_dir_commit (lfs=0x555555761120 <lfs>, dir=0x7fffffffe0ec, attrs=0x7fffffffe060, attrcount=2) at lfs.c:1723
commit = {block = 0, off = 94, ptag = 3491757060, crc = 4294967295, begin = 94, end = 120}
err = 32767
deletetag = 4294967295
createtag = 4294967295
__PRETTY_FUNCTION__ = "lfs_dir_commit"
copy = {pair = {2, 0}, rev = 1431653632, off = 21845, etag = 0, count = 98, erased = false, split = false, tail = {537921536, 4288921339}}
#10 in lfs_file_sync (lfs=0x555555761120 <lfs>, file=0x7fffffffe0e0) at lfs.c:2601
type = 513
buffer = 0x555555774210
size = 0
ctz = {head = 0, size = 0}
err = 0
#11 in lfs_file_close (lfs=0x555555761120 <lfs>, file=0x7fffffffe0e0) at lfs.c:2404
err = 21845
#12 in main () at main_test.cpp:60
fileA = {next = 0x0, id = 1, type = 1 '\001', m = {pair = {0, 1}, rev = 15, off = 73, etag = 3491757060, count = 2, erased = true, split = false,
tail = {4294967295, 4294967295}}, ctz = {head = 4294967294, size = 0}, flags = 1048833, pos = 0, block = 21845, off = 142, cache = {
block = 4294967294, off = 0, size = 2, buffer = 0x555555774210 "\377$\255\373\377\177"}, cfg = 0x55555555f180 <defaults>}
fileB = {next = 0x0, id = 2, type = 1 '\001', m = {pair = {0, 1}, rev = 15, off = 94, etag = 3491757060, count = 3, erased = true, split = false,
tail = {4294967295, 4294967295}}, ctz = {head = 4294967294, size = 0}, flags = 1048833, pos = 0, block = 0, off = 4146172768, cache = {
block = 4294967294, off = 0, size = 2, buffer = 0x555555774210 "\377$\255\373\377\177"}, cfg = 0x55555555f180 <defaults>}
fileC = {next = 0x0, id = 2, type = 1 '\001', m = {pair = {0, 1}, rev = 15, off = 94, etag = 3491757060, count = 3, erased = true, split = false,
tail = {4294967295, 4294967295}}, ctz = {head = 4294967294, size = 0}, flags = 1115137, pos = 0, block = 32767, off = 4149439232, cache = {
block = 4294967294, off = 0, size = 2, buffer = 0x555555774210 "\377$\255\373\377\177"}, cfg = 0x55555555f180 <defaults>}
__PRETTY_FUNCTION__ = "int main()"
Thanks for raising an issue and the great example, sorry about the long delay. I've pushed up a fix on the v2-alpha branch: https://github.com/ARMmbed/littlefs/pull/85
The issue was with lfs_file_sync
not setting the LFS_F_ERRED
flag on error. This prevents lfs_file_close
from creating further problems, which is needed for cleaning up the file resources. Otherwise lfs_file_close
tries to write to the already dirty file cache as a part of writing out the file.
Properly handling all block device errors is one area that needs work and would benefit greatly from actual coverage information.
Adafruit nRF52 board support V1.3.0 still has this problem. file system is un-stable. board locks up after this error.
Seems to triggered by truncate(0) This method fails
bool saveLastCmd(SafeString &sfCmd) {
if (debugPtr) {
debugPtr->print("calling saveLastCmd (");
debugPtr->print(sfCmd); debugPtr->println(")");
}
if (!initialzeFileSystem()) {
return fileSystemInitializedResult;
}
sfCmd.trim();
if (sfCmd.endsWith(',')) {
sfCmd.removeLast(1); // remove last char
}
File file(InternalFS);
if (!(file.open(FILENAME, FILE_O_WRITE))) {
if (debugPtr) {
debugPtr->print("Error: File: '");
debugPtr->print(FILENAME);
debugPtr->println("' failed to open");
}
return false;
}
// else
if (!file.truncate(0)) { // truncate() truncates at current file pointer position!!
if (debugPtr) {
debugPtr->print("Error: Positioning to 0 for file '");
debugPtr->print(FILENAME);
debugPtr->println("'");
}
file.close();
return false;
}
if (debugPtr) {
debugPtr->print(" write "); debugPtr->print(sfCmd); debugPtr->println();
}
size_t count = file.write(sfCmd.c_str(), sfCmd.length());
file.close();
if (count != sfCmd.length()) {
if (debugPtr) {
debugPtr->print("Error: Writing cmd '");
debugPtr->print(sfCmd);
debugPtr->println(" to file '");
debugPtr->print(FILENAME);
debugPtr->println("'");
}
if (!InternalFS.remove(FILENAME)) {
if (debugPtr) {
debugPtr->print("Error: Delete of file '");
debugPtr->print(FILENAME);
debugPtr->println("' failed");
}
}
return false;
}
return true;
}
This method seems to work (so far)
bool saveLastCmd(SafeString &sfCmd) {
if (debugPtr) {
debugPtr->print("calling saveLastCmd (");
debugPtr->print(sfCmd); debugPtr->println(")");
}
if (!initialzeFileSystem()) {
return fileSystemInitializedResult;
}
sfCmd.trim();
if (sfCmd.endsWith(',')) {
sfCmd.removeLast(1); // remove last char
}
InternalFS.remove(FILENAME);
File file(InternalFS);
if (!(file.open(FILENAME, FILE_O_WRITE))) {
if (debugPtr) {
debugPtr->print("Error: File: '");
debugPtr->print(FILENAME);
debugPtr->println("' failed to open");
}
return false;
}
if (debugPtr) {
debugPtr->print(" write "); debugPtr->print(sfCmd); debugPtr->println();
}
size_t count = file.write(sfCmd.c_str(), sfCmd.length());
file.close();
if (count != sfCmd.length()) {
if (debugPtr) {
debugPtr->print("Error: Writing cmd '");
debugPtr->print(sfCmd);
debugPtr->println(" to file '");
debugPtr->print(FILENAME);
debugPtr->println("'");
}
if (!InternalFS.remove(FILENAME)) {
if (debugPtr) {
debugPtr->print("Error: Delete of file '");
debugPtr->print(FILENAME);
debugPtr->println("' failed");
}
}
return false;
}
return true;
}
The following test case:
Dies with
lfs.c:223: lfs_bd_prog: Assertion 'pcache->block == 0xffffffff' failed.
It looks as though the lfs_file_sync isn't properly clearing out pcache if the program fails with a non-LFS_ERR_CORRUPT error code.
Stack trace:
Other info:
10dfc36 Fixed issue with long names causing unbounded recursion
(v2-alpha)