realm-java: Fatal signal 11 (SIGSEGV) from Java_io_realm_internal_UncheckedRow_nativeGetString
Goal
No crashes
Expected Results
No crashes
Actual Results
Crashing consistently for one affected user w/a seemingly corrupted DB state
A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'samsung/dreamqltesq/dreamqltesq:8.0.0/R16NW/G950USQU5CRG3:user/release-keys'
Revision: '12'
ABI: 'arm64'
A/DEBUG: pid: 27327, tid: 27372, name: RxComputationTh >>> com.preveil.preveil <<<
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x78713fe000
x0 00000078704e4380 x1 00000078704e437f x2 0000007871254317 x3 00000078704e43d8
x4 00000078704e4380 x5 000000786f5a9d7d x6 0000000000000000 x7 0000000000000000
x8 0000000000000000 x9 0000000000000000 x10 0000000000000001 x11 0000000000000000
x12 000000786fc05210 x13 0000000001000000 x14 0000000000000000 x15 0000000000000000
x16 000000787380e570 x17 000000788e181970 x18 0000000000000020 x19 00000078704e4380
x20 000000787376a000 x21 00000078704e4540 x22 00000078713fe000 x23 00000078704e4380
x24 00000078704e437f x25 0000000000000001 x26 00000078704e4568 x27 00000078704e45d0
x28 00000078704e4570 x29 00000078704e42f0 x30 00000078735424e0
sp 00000078704e42f0 pc 00000078735424cc pstate 0000000020000000
09-04 11:23:56.963 27385-27385/? A/DEBUG: backtrace:
#00 pc 000000000003b4cc /data/app/com.preveil.preveil-FG01oMB2aWtfSFb4Aipq1w==/lib/arm64/librealm-jni.so
#01 pc 00000000000be5d8 /data/app/com.preveil.preveil-FG01oMB2aWtfSFb4Aipq1w==/lib/arm64/librealm-jni.so
#02 pc 00000000000b6f28 /data/app/com.preveil.preveil-FG01oMB2aWtfSFb4Aipq1w==/lib/arm64/librealm-jni.so (Java_io_realm_internal_UncheckedRow_nativeGetString+92)
#03 pc 0000000000510d00 /system/lib64/libart.so (art_quick_generic_jni_trampoline+144)
#04 pc 000000000000f8bc /dev/ashmem/dalvik-jit-code-cache_27327_27327 (deleted)
Steps & Code to Reproduce
So far, only one known user has encountered this issue. This user will encounter the crash every time they launch the app. Fortunately, I have access to the user’s device and have hooked it up to the debugger. There seems to be 3 RealmObject
s (all of the same ChildObject
type described below) out of hundreds which have somehow corrupted, and trying to access any of these 3 objects will seg fault. I’ve tried accessing these objects w/in a DynamicRealm
, but that seg faults as well.
Although the stacktrace above happens on a RxComputation
thread, when I run everything on the main thread, the crash persists.
Code Sample
Unfortunately I can’t share specific code or realm files, but I’ll describe the relevant schema structure and access which is causing the crash.
open class ParentObject : RealmObject() {
@PrimaryKey
var identifier = UUID.randomUUID().toString()
var children = RealmList<ChildObject>()
// other properties
}
open class ChildObject : RealmObject() {
@PrimaryKey
var identifier = UUID.randomUUID().toString()
// other properties
}
// Elsewhere, on app launch
val parents = Realm.getDefaultInstance().where(ParentObject::class.java).findAll()
parents.forEach { parentObject ->
parentObject.children.forEach { childObject ->
// For hundreds of ChildObjects, this is totally fine
// But for 3 seemingly corrupted objects, this seg faults
val property = childObject.property
}
}
Version of Realm and tooling
Realm version(s): 5.3.1 w/encryption enabled
Realm sync feature enabled: no
Android Studio version: 3.1.3
Which Android version and device: Samsung Galaxy S8 running Android 8
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 80 (28 by maintainers)
Hutlihut (sorry non-danes: https://www.youtube.com/watch?v=QdFK6VbuIC0)
I managed to reproduce in an isolated unit test on an x86 emulator:
Stacktrace:
Also seeing this assertion failure:
This unit test does indeed create a large number of both writer and reader threads.
Further observations:
This matches the different kinds we seen so far.
We believe we have identified the root cause: https://github.com/realm/realm-core/issues/3427
Our team has active paid support. We provide 2 or 3 corrupted databases with encryption keys. Unfortunately, no update. And now we consider painful database switch, because of this and similar native crashes. That sad…
I have no knowledge about the inner workings of Realm-Core but I want to understand why realm files cannot be validated internally to not contain corrupt or erroneous data and auto-recover in a clean slate. The fact that realm files can go “corrupt” and require a full uninstall/reinstall of the application is very bad for such a widely used database.
Also, has anyone tried to build their own encryption layer/interface and disable the encryption done by realm? We would have tried something like this if it wasn’t for our encryption key rotating every so often.
Tentative fix in progress: https://github.com/realm/realm-core/pull/3429
Logcat output attached. Do you need something else?
crush_report_realm_honor.log crush_report_realm_xiaomi.log
That’s good. But our app make writes in one thread and open few subscriptions (changelistener) depending on active screen. My observations:
@cmelchior yes, x86
No, 6.0 only breaks some Sync API’s: https://github.com/realm/realm-java/blob/master/CHANGELOG.md#6002019-10-01
7.0 will contain the Core 6 upgrade which will change the file format.
We will start logging every realm transaction to Firebase NDK Crashlytics so we can see exactly what steps lead to these crashes. I hope other people will do the same so we can discover patterns.
@yohanan
You pretty much can’t.
We put a number of validating realm transactions and the realm init code around this wrapper:
Then on startup we delete the realm files if the
FLAG_END
was not hit. It’s not pretty but it works for native crashes triggered during startup. At least sometimes our users can continue rather than uninstall the app. But the corruption sometimes happens on a single field, or during background syncs and then your pretty much screwed (unless you use a timer approach).Also, cmelchior mentioned that reading the corrupt string field on javascript does not cause a crash but silently fails, so I’m wondering how javascript is able to do that.
Well that’s not any solution, except you get rid of the crashes. Not even saying that catching native crashes is problematic.
That could actually be very helpful and maybe a “quickest” solution to the problem, but I still don’t understand why these transaction errors occur only on encrypted db’s.
Corrupted DB emailed to help@realm.io