Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiprocess access crash #137

Closed
mike07026 opened this issue Apr 20, 2022 · 2 comments
Closed

multiprocess access crash #137

mike07026 opened this issue Apr 20, 2022 · 2 comments
Assignees
Labels

Comments

@mike07026
Copy link

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 ()
@symisc symisc self-assigned this Apr 20, 2022
@symisc symisc added the bug label Apr 25, 2022
@symisc
Copy link
Owner

symisc commented Apr 25, 2022

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.

@symisc symisc closed this as completed Apr 25, 2022
symisc added a commit that referenced this issue Apr 25, 2022
Refer to: #137 for a detailed overview...
symisc added a commit that referenced this issue Apr 25, 2022
symisc added a commit that referenced this issue Apr 25, 2022
@mike07026
Copy link
Author

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.

@symisc Thank you very much. And I will test it later ^_^

symisc added a commit that referenced this issue May 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants