symisc / unqlite

An Embedded NoSQL, Transactional Database Engine
https://unqlite.symisc.net
Other
2.09k stars 163 forks source link

unqlite NPE on Android #135

Open achieverForever opened 2 years ago

achieverForever commented 2 years ago

I encountered a NPE in unqliteOsWrite in Android multithreaded environment. I think it's a multithreaded issue, however UNQLITE_ENABLE_THREADS compiler flag has been enabled and unqlite_lib_is_threadsafe returns true.

Exception code:

Process Name: 'xxx'
Thread Name: 'CACHE_INDEXER'
signal 11 (SIGSEGV)  code 1 (SEGV_MAPERR)  fault addr 0000000000000000
  x0   0000000000000000  x1   0000007bbf9249d0  x2   0000000000000020  x3   0000000000003224
  x4   0000000000000021  x5   00000000fbd23f84  x6   0000000000000000  x7   00000000017301ae
  x8   0000000000000000  x9   0000000000000000  x10  000000000000000d  x11  0000000000000000
  x12  0000000000000000  x13  0000000000000f99  x14  000000000000000f  x15  0000007a8640a3d0
  x16  0000007a7f3d98e8  x17  0000007cd3817738  x18  0000000000001000  x19  0000007b941e7f14
  x20  0000007a8658c21c  x21  0000000000000000  x22  0000000000000020  x23  0000007bbf9249d0
  x24  0000007bbf9249d0  x25  0000007b7abaf020  x26  0000007b7abae1b0  x27  0000007b7abaf020
  x28  0000007bc5e93414  x29  0000007b7abae310  x30  0000007a7f35e758
  sp   0000007b7abae130  pc   0000007a7f35e884  pstate 0000000000001000

And desymbolized:

unqliteOsWrite
/home/admin/jenkins_sigma_k8s2/workspace/android_so_build_2/ccdn/src/unicache/basic/mds/unqlite.c:24507
lhStoreCell
/home/admin/jenkins_sigma_k8s2/workspace/android_so_build_2/ccdn/src/unicache/basic/mds/unqlite.c:22721
lhRecordInstall
/home/admin/jenkins_sigma_k8s2/workspace/android_so_build_2/ccdn/src/unicache/basic/mds/unqlite.c:23082
unqlite_kv_store
/home/admin/jenkins_sigma_k8s2/workspace/android_so_build_2/ccdn/src/unicache/basic/mds/unqlite.c:4246

It seems like there is a NPE in the following code?

UNQLITE_PRIVATE int unqliteOsWrite(unqlite_file *id, const void *pBuf, unqlite_int64 amt, unqlite_int64 offset)
{
  return id->pMethods->xWrite(id, pBuf, amt, offset);
}

Thanks for your help!

symisc commented 2 years ago

Make sure access to the shared UnQLite handle is serialized. This is easily done via these API calls before opening any database (when your program starts):

        unqlite_lib_config(UNQLITE_LIB_CONFIG_THREAD_LEVEL_MULTI);
    unqlite_lib_init();
    if (!unqlite_lib_is_threadsafe()) {
        std::cerr << "UnQLite must be compiled with threading support. Aborting!" << std::endl;
        return 1;
    }