multiprocess access crash
mike07026 opened this issue · comments
version: unqlite 1.1.9 (master branch)
platform : mac, windows
description: multiprocess access crash
how to reproduce:
step 1: start process A, open db, write, commit and wait forever(keep database open)
step 2: start process B, open db, write, commit, write commit, and crash!
[process A] main.cpp
extern "C" {
#include "unqlite.h"
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
unqlite* db = NULL;
int ret = UNQLITE_OK;
do {
ret = unqlite_open(&db, "/Users/ali/code/test.db", UNQLITE_OPEN_CREATE);
if (ret != UNQLITE_OK) break;
ret = unqlite_kv_store(db, "key", 3, "value", 5);
if (ret != UNQLITE_OK) break;
ret = unqlite_commit(db);
if (ret != UNQLITE_OK) break;
} while(0);
if (ret == UNQLITE_OK) {
printf("process A: db test ready\n");
}
else {
printf("process A: db test fail");
}
while(1) {
getchar(); // wait forever
}
return 0;
}
[process B] main.cpp
extern "C" {
#include "unqlite.h"
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
unqlite* db = NULL;
unqlite_open(&db, "/Users/ali/code/test.db", UNQLITE_OPEN_CREATE);
unqlite_begin(db);
unqlite_kv_store(db, "key", 3, "value", 5);
unqlite_commit(db);
unqlite_begin(db);
unqlite_kv_store(db, "key", 3, "value", 5);
printf("process B, i am going to crash");
unqlite_commit(db); // crash here
return 0;
}
[process B backtrace]
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x000000010001aa5c in unqliteOsWrite at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:52480
#1 0x000000010001bad5 in WriteInt32 at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:55574
#2 0x000000010001b63f in unqliteFinalizeJournal at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:56961
#3 0x0000000100067240 in pager_commit_phase1 at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:57152
#4 0x00000001000092c5 in unqlitePagerCommit at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:57290
#5 0x0000000100009297 in unqlite_commit at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/unqlite.c:6190
#6 0x0000000100067cc2 in main at /Users/ali/code/dev_test/test_unqlite_2/test_unqlite_2/main.cpp:22
#7 0x00000001000b94fe in start ()
Hi @mike07026,
Thanks for reporting this bug. We were effectively be able to reproduce this extremely rare bug where two distinct process share the same database, one hangs, the other tries to open a journal file without success due to a failure to acquire an exclusive lock on the database.
The crash cause is a null pointer dereferencing on the function unqliteFinalizeJournal()
when UnQLite tries to finalize the journal file. The crash could be easily avoided by the checking the return code of each UnQLite public function rc != UNQLITE_OK
The latest hot patch fix the whole issue. Please update as soon as possible.
Hi @mike07026,
Thanks for reporting this bug. We were effectively be able to reproduce this extremely rare bug where two distinct process share the same database, one hangs, the other tries to open a journal file without success due to a failure to acquire an exclusive lock on the database. The crash cause is a null pointer dereferencing on the function
unqliteFinalizeJournal()
when UnQLite tries to finalize the journal file. The crash could be easily avoided by the checking the return code of each UnQLite public functionrc != UNQLITE_OK
The latest hot patch fix the whole issue. Please update as soon as possible.
@symisc Thank you very much. And I will test it later ^_^