Exception when printing dir contents after file deletion
Hi,
I'm playing a bit with the SPIFFS library to get a fs on an ESP32 with an external flash chip. One of the tests I did was creating a bunch of files and printing their properties, and it worked as expected. I proceeded to delete one of them and wanted to display the dir contents to see that the file was deleted, but I get an unhandled exception and the execution stops. This is the relevant piece of code.
spiffs_DIR d;
struct spiffs_dirent e;
struct spiffs_dirent *pe = &e;
SPIFFS_opendir(&fs, "/", &d);
while ((pe = SPIFFS_readdir(&d, pe))) {
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
}
SPIFFS_closedir(&d);
s32_t res = SPIFFS_remove(&fs, "third_file");
SPIFFS_CHECK(res);
printf("deleted\n");
//This causes an error, I don't know why...
SPIFFS_opendir(&fs, "/", &d);
printf("open\n");
while ((pe = SPIFFS_readdir(&d, pe))) {
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
}
SPIFFS_closedir(&d);
my_file [0001] size:12
another_file [0002] size:13
third_file [0003] size:12
deleted
open
Guru Meditation Error of type StoreProhibited occurred on core 0. Exception was unhandled.
Register dump:
PC : 0x400dbd43 PS : 0x00060430 A0 : 0x800dd541 A1 : 0x3ffb6670
0x400dbd43: spiffs_read_dir_v at C:/Users/Joel/Workspace/get-started/_03_SPIFFS_test/main/spiffs_hydrogen.c:170
A2 : 0x000000c0 A3 : 0x00008001 A4 : 0x000000c0 A5 : 0x00000001
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x800dbd25 A9 : 0x3ffb6640
A10 : 0x00000000 A11 : 0x00000001 A12 : 0x3ffb2360 A13 : 0x00000840
A14 : 0x0000002d A15 : 0x3ffb6670 SAR : 0x0000001f EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
Backtrace: 0x400dbd43:0x3ffb6670 0x400dd53e:0x3ffb66c0 0x400dc5a9:0x3ffb6700 0x400dc7c2:0x3ffb6740 0x400d0806:0x3ffb67b0
0x400dbd43: spiffs_read_dir_v at C:/Users/Joel/Workspace/getstarted/_03_SPIFFS_test/main/spiffs_hydrogen.c:170
0x400dd53e: spiffs_obj_lu_find_entry_visitor at C:/Users/Joel/Workspace/getstarted/_03_SPIFFS_test/main/spiffs_nucleus.c:1158
0x400dc5a9: SPIFFS_readdir at C:/Users/Joel/Workspace/getstarted/_03_SPIFFS_test/main/spiffs_hydrogen.c:170
0x400dc7c2: app_main at C:/Users/Joel/Workspace/getstarted/_03_SPIFFS_test/main/spiffs_hydrogen.c:170
0x400d0806: main_task at C:/Users/Joel/Workspace/hub/lib/esp-idf/components/esp32/cpu_start.c:331
Can somebody point me to my error? do I need to "refresh" the fs after a delete or something like that?
Thanks!
hi joel,
i just created a testcase with the details you provided. i get a core dump as well. just checking with valgrind ...
cheers robert
output: TEST 66/91 : running test test_joel create and write first_file................ create and write second_file................ create and write third_file................ first_file [0001] size:512 second_file [0010] size:512 third_file [001f] size:512 deleted open Segmentation fault (core dumped)
deep inside: ==23883== Invalid write of size 2 ==23883== at 0x40CBF7: spiffs_read_dir_v (spiffs_hydrogen.c:1044) ==23883== by 0x4019A0: spiffs_obj_lu_find_entry_visitor (spiffs_nucleus.c:177) ==23883== by 0x40CD14: SPIFFS_readdir (spiffs_hydrogen.c:1070) ==23883== by 0x428A78: __test_test_joel (test_bugreports.c:1270) ==23883== by 0x429497: run_tests (testrunner.c:192) ==23883== by 0x411EFE: main (main.c:9)
do not think about loooking up the linenumbers in your copy of spiffs. i made a few changes :-)
Just a superquick glance, not verified at all, but I think the problem is this:
spiffs_DIR d;
struct spiffs_dirent e;
struct spiffs_dirent *pe = &e;
SPIFFS_opendir(&fs, "/", &d);
while ((pe = SPIFFS_readdir(&d, pe))) {
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
}
// **** The while loop stopped as pe now is NULL ...
SPIFFS_closedir(&d);
s32_t res = SPIFFS_remove(&fs, "third_file");
SPIFFS_CHECK(res);
printf("deleted\n");
//This causes an error, I don't know why...
SPIFFS_opendir(&fs, "/", &d);
printf("open\n");
// **** ... meaning SPIFFS_readdir is fed with NULL here - kaboom
// **** instead, try reinitiating pe before
// pe = &e;
while ((pe = SPIFFS_readdir(&d, pe))) {
printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size);
}
SPIFFS_closedir(&d);
yes, abs. correct. in spiffs_read_dir_v a simple sanity check is needed. i would add: if (NULL == user_var_p) { return SPIFFS_VIS_END; }
a kaboom in the app due to an error in the user logic is problematic. gracefull degredation would be nice.
Hi guys,
thanks for your quick replies and going through all that effort to solve my issue. I'm really grateful.
I'm away from my dev kit and won't be able to test until Monday. Am I correct in thinking that, as pellepl mentioned, I should reset the value of the pointer pe before the second pass? I mean, the problem is in how I am doing things, right?
hi joel, yes, you are right. i came bottom up with the same conclusion.
you don't need a dev kit to test. just a pc and the test suite is enough for verification.
I've never used this test suite, do you have a tutorial you can point me to, to start playing around with it?
:-) easy, what base os do you use? this would be part of the wiki i think. and it is off topic.
I use windows
i try to prepare a small guide.