torarnv / sparsebundlefs

FUSE filesystem for reading macOS sparse-bundle disk images
BSD 2-Clause "Simplified" License
330 stars 38 forks source link

Hangs with 100% CPU usage #30

Closed isundaylee closed 5 years ago

isundaylee commented 5 years ago

I had a similar issue with #29 where sparsebundlefs hangs with 100% CPU usage. I did a little bit debugging, and found that there was an infinite cycle while iterating through sparsebundle->open_files. Relevant GDB transcript (note the cycle of bands 1b0->1b1->...->1b0->1b1->...):

(gdb) p iter
$3 = {first = "/../../xxxx.sparsebundle/bands/1b0", second = 371} <- 1b0 first time
(gdb) p ++iter
$4 = {first = "/../../xxxx.sparsebundle/bands/1b1", second = 370}
(gdb) p ++iter
$5 = {first = "/../../xxxx.sparsebundle/bands/1b2", second = 369}
(gdb) p ++iter
$6 = {first = "/../../xxxx.sparsebundle/bands/1b3", second = 372}
(gdb) p ++iter
$7 = {first = "/../../xxxx.sparsebundle/bands/1b4", second = 373}
(gdb) p ++iter
$8 = {first = "/../../xxxx.sparsebundle/bands/1b5", second = 374}
(gdb) p ++iter
$9 = {first = "/../../xxxx.sparsebundle/bands/1b6", second = 375}
(gdb) p ++iter
$10 = {first = "/../../xxxx.sparsebundle/bands/1b7", second = 367}
(gdb) p ++iter
$11 = {first = "/../../xxxx.sparsebundle/bands/1b8", second = 368}
(gdb) p ++iter
$12 = {first = "/../../xxxx.sparsebundle/bands/1b9", second = 366}
(gdb) p ++iter
$13 = {first = "/../../xxxx.sparsebundle/bands/1ba", second = 365}
(gdb) p ++iter
$14 = {first = "/../../xxxx.sparsebundle/bands/1af", second = 48}
(gdb) p ++iter
$15 = {first = "/../../xxxx.sparsebundle/bands/1b0", second = 371} <- 1b0 second time
(gdb) p ++iter
$16 = {first = "/../../xxxx.sparsebundle/bands/1b1", second = 370}
(gdb) p ++iter
$17 = {first = "/../../xxxx.sparsebundle/bands/1b2", second = 369}
(gdb) p ++iter
$18 = {first = "/../../xxxx.sparsebundle/bands/1b3", second = 372}
(gdb) p ++iter
$19 = {first = "/../../xxxx.sparsebundle/bands/1b4", second = 373}
(gdb) p ++iter
$20 = {first = "/../../xxxx.sparsebundle/bands/1b5", second = 374}
(gdb) p ++iter
$21 = {first = "/../../xxxx.sparsebundle/bands/1b6", second = 375}
(gdb) p ++iter
$22 = {first = "/../../xxxx.sparsebundle/bands/1b7", second = 367}
(gdb) p ++iter
$23 = {first = "/../../xxxx.sparsebundle/bands/1b8", second = 368}
(gdb) p ++iter
$24 = {first = "/../../xxxx.sparsebundle/bands/1b9", second = 366}
(gdb) p ++iter
$25 = {first = "/../../xxxx.sparsebundle/bands/1ba", second = 365}
(gdb) p ++iter
$26 = {first = "/../../xxxx.sparsebundle/bands/1af", second = 48}
(gdb) p ++iter
$27 = {first = "/../../xxxx.sparsebundle/bands/1b0", second = 371} <- 1b0 third time
(gdb) p ++iter
$27 = {first = "/../../xxxx.sparsebundle/bands/1b1", second = 370}

The infinite cycle causes the iteration loop in sparsebundlefs.cpp line 365-368 to go on indefinitely.

Seems like this might be a multi-threading issue, since I believe std::map is not guaranteed to be thread-safe.

torarnv commented 5 years ago

Does the problem go away when running with -s ?

isundaylee commented 5 years ago

I have been running it with -s for a couple days and the problem hasn't been reproduced yet. So I'd say that it goes away with -s.

torarnv commented 5 years ago

Assumed fixed by 414f30f268ea7 (until we can support multiple threads)