symisc/unqlite

Segfault & Busy Loop When Sharing Database Between Processes

VaslD opened this issue · 0 comments

VaslD commented

I was experimenting with sharing a single database between iOS app and app extensions, when I encountered an always reproducible crash. (It seems to reference #135 but I haven't got time to dig deep.)

To easily reproduce it, I write a benchmark app that stores random key-values and fetches it back, then sleeps for about half a second, rinses and repeats for almost indefinitely. When I launch this tool twice (operating on the same database file), one process crashes.

Screenshot.2024-04-23.14.53.59.mp4

The crash isn't deterministic (the first or the second to launch), contrary to what the video shows. (The video was cut short due to GitHub size limit.) But I can never have both survive long enough.

Also, after that one process crashes, it sends the other into an UNQLITE_BUSY (-14) loop, which I assume is caused by either unrelinquished UNIX lock or corrupted book-keeping, making the whole situation fatal unless I close and reopen the database file everywhere.

Screenshot 2024-04-23 15 12 40@2x

Further investigation shows that the file descriptor was somehow set to null on a valid database (unqlite *) and pager (Pager *).

Screenshot 2024-04-23 15 36 34@2x


unqlite 1.1.9 compiled with -DUNQLITE_ENABLE_THREADS, on macOS 14.4 and iOS 17.0