Native runtime crash from SQLCipher for Android


#1

Hi, I’m trying to use SQLCipher in Android Studio following your instruction but once the program reaches SQLiteDatabase.loadLibs(this); it fails both on x86 emulator and on my physical device (Xiaomi Mi4).

Device error output:

01-26 20:56:42.850 12905-12905/com.btcontract.wallet E/dalvikvm: ERROR: couldn't find native method
01-26 20:56:42.850 12905-12905/com.btcontract.wallet E/dalvikvm: Requested: Lnet/sqlcipher/database/SQLiteDatabase;.dbopen:(Ljava/lang/String;I)V
01-26 20:56:42.860 12905-12905/com.btcontract.wallet E/dalvikvm: VM aborting
01-26 20:56:42.860 12905-12905/com.btcontract.wallet A/libc: Fatal signal 6 (SIGABRT) at 0x00003269 (code=-6), thread 12905 (contract.wallet)

Emulator error output:

01-26 20:59:23.040 24802-24802/com.btcontract.wallet E/art: Failed to register native method net.sqlcipher.database.SQLiteDatabase.dbopen(Ljava/lang/String;I)V in /data/app/com.btcontract.wallet-2/base.apk
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art: ----- class 'Lnet/sqlcipher/database/SQLiteDatabase;' cl=0x12d2a2e0 -----
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   objectSize=476 (136 from super)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   access=0x8008.0001
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   super='java.lang.Class<net.sqlcipher.database.SQLiteClosable>' (cl=0x12d2a2e0)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   vtable (5 entries, 2 in super):
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      0: void net.sqlcipher.database.SQLiteDatabase.finalize()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      1: boolean net.sqlcipher.database.SQLiteDatabase.isOpen()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      2: void net.sqlcipher.database.SQLiteDatabase.lock()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      3: void net.sqlcipher.database.SQLiteDatabase.onAllReferencesReleased()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      4: void net.sqlcipher.database.SQLiteDatabase.unlock()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   direct methods (10 entries):
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      0: void net.sqlcipher.database.SQLiteDatabase.<clinit>()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      1: void net.sqlcipher.database.SQLiteDatabase.checkLockHoldTime()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      2: void net.sqlcipher.database.SQLiteDatabase.closeClosable()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      3: void net.sqlcipher.database.SQLiteDatabase.dbclose()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      4: void net.sqlcipher.database.SQLiteDatabase.deallocCachedSqlStatements()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      5: java.lang.String net.sqlcipher.database.SQLiteDatabase.getTime()
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      6: void net.sqlcipher.database.SQLiteDatabase.loadICUData(android.content.Context, java.io.File)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      7: void net.sqlcipher.database.SQLiteDatabase.loadLibs(android.content.Context)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      8: void net.sqlcipher.database.SQLiteDatabase.loadLibs(android.content.Context, java.io.File)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      9: void net.sqlcipher.database.SQLiteDatabase.setICURoot(java.lang.String)
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   static fields (4 entries):
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      0: java.lang.String[] net.sqlcipher.database.SQLiteDatabase.CONFLICT_VALUES
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      1: java.util.regex.Pattern net.sqlcipher.database.SQLiteDatabase.EMAIL_IN_DB_PATTERN
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      2: java.util.WeakHashMap net.sqlcipher.database.SQLiteDatabase.sActiveDatabases
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      3: int net.sqlcipher.database.SQLiteDatabase.sQueryLogTimeInMillis
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:   instance fields (11 entries):
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      0: java.util.Map net.sqlcipher.database.SQLiteDatabase.mCompiledQueries
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      1: long net.sqlcipher.database.SQLiteDatabase.mLastLockMessageTime
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      2: java.util.concurrent.locks.ReentrantLock net.sqlcipher.database.SQLiteDatabase.mLock
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      3: long net.sqlcipher.database.SQLiteDatabase.mLockAcquiredThreadTime
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      4: long net.sqlcipher.database.SQLiteDatabase.mLockAcquiredWallTime
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      5: boolean net.sqlcipher.database.SQLiteDatabase.mLockingEnabled
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      6: int net.sqlcipher.database.SQLiteDatabase.mNativeHandle
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      7: java.lang.String net.sqlcipher.database.SQLiteDatabase.mPath
01-26 20:59:23.041 24802-24802/com.btcontract.wallet E/art:      8: java.util.WeakHashMap net.sqlcipher.database.SQLiteDatabase.mPrograms
01-26 20:59:23.042 24802-24802/com.btcontract.wallet E/art:      9: java.lang.Throwable net.sqlcipher.database.SQLiteDatabase.mStackTrace
01-26 20:59:23.042 24802-24802/com.btcontract.wallet E/art:     10: java.lang.String net.sqlcipher.database.SQLiteDatabase.mTimeClosed
01-26 20:59:23.042 24802-24802/com.btcontract.wallet A/art: art/runtime/jni_internal.cc:497] JNI FatalError called: RegisterNatives failed for 'net/sqlcipher/database/SQLiteDatabase'; aborting...
01-26 20:59:23.254 24802-24802/com.btcontract.wallet A/art: art/runtime/barrier.cc:90] Check failed: count_ == 0 (count_=-1, 0=0) Attempted to destroy barrier with non zero count
01-26 20:59:23.254 24802-24802/com.btcontract.wallet A/art: art/runtime/runtime.cc:366] Runtime aborting --- recursively, so no thread-specific detail!
01-26 20:59:23.254 24802-24802/com.btcontract.wallet A/art: art/runtime/runtime.cc:366] 
01-26 20:59:23.254 24802-24802/com.btcontract.wallet A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 24802 (contract.wallet)

SQLCipher for Android 3.3.1-2 Release
#2

Can you please verify your apk is properly including the SQLCipher for Android native libraries? You can dump the packaged content of the apk with apktool.


#3

Sure, here’s how it looks:

anton@anton-VPCCW2S1R:~$ tree '/home/anton/app-debug/lib' 
/home/anton/app-debug/lib
├── armeabi
│   ├── libdatabase_sqlcipher.so
│   ├── libscrypt.so
│   ├── libsqlcipher_android.so
│   └── libstlport_shared.so
├── armeabi-v7a
│   ├── libdatabase_sqlcipher.so
│   ├── libscrypt.so
│   ├── libsqlcipher_android.so
│   └── libstlport_shared.so
├── x86
│   ├── libdatabase_sqlcipher.so
│   ├── libscrypt.so
│   ├── libsqlcipher_android.so
│   └── libstlport_shared.so
└── x86_64
    ├── darwin
    │   └── libscrypt.dylib
    ├── freebsd
    │   └── libscrypt.so
    └── linux
        └── libscrypt.so

7 directories, 15 files

#4

Hi @anton.kumaigorodskiy

The reason you are likely receiving this issue is that SQLCipher for Android is only built for armeabi, armeabi-v7a, and x86 platforms. You are likely deploying to a x86_64 device so Android uses the corresponding folder for resolving all native libraries (i.e., x86_64), as such the SQLCipher for Android binaries are not present in your x86_64 folder. A work around is to remove the x86_64 native libraries entirely, it should fall back to x86 folder for x86_64 devices.


#5

Thanks for suggestions! The issue was not there, however, it was that I have minifyEnabled true in Gradle settings and it looks like ProGuard was cutting some net.sqlcipher.* classes off.

Adding the following to ProGuard settings solved the problem:

-keep class net.sqlcipher.** { *; }
-dontwarn net.sqlcipher.**

#6

Hello @anton.kumaigorodskiy

Great, I’m glad to hear you were able to solve the issue! Please note, you will see the issue I describe above on an x86_64 device so you may consider adjusting for that as well.


#7

Can You share whole code of gradle to resolve above issues?


#8

yes,