Add a different native library (not Realm) to my Android project, without breaking Realm when in debug mode.
Actual Results
I have an Android app which uses Realm, and works fine. But when I add a native library to the app (not Realm), then things stop working. It seems that changing my build.gradle to specify an externalNativeBuild which references CMake causes Realm to break BUT ONLY IN DEBUG MODE.
Steps & Code to Reproduce
Steps to reproduce:
1) Integrate Realm to your Android app via maven.
2) Update my build.grade with this (needed for the new library I'm adding):
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-19', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_ARM_NEON=TRUE', '-DANDROID_STL=c++_static', "-DPATH_TO_SUPERPOWERED:STRING=${superpowered_sdk_path}"
cFlags '-O3', '-fsigned-char' // full optimization, char data type is signed
cppFlags '-fsigned-char', "-I${superpowered_sdk_path}"
}
}
3) Run the app in debug mode
4) LLDB debugger hits 3 breakpoints, although code is not visible. The error for each of these breakpoints is as follows:
5) Even though I have breakpoints in my Java code, none of them are triggered.
6) The app crashes, and logcat show an exception from those Java lines on which I had breakpoints set in step 5. The failure occurs because I am expecting to find a Realm object which does not exist. It appears that the crash from the LLDB debugger is preventing Realm from working properly, so my Java logic is breaking too.
6) After the crash, looking at the logcat, I also see some failures around the SIGSEGV:
2021-02-01 11:42:48.739 32229-32229/? E/adbd: failed to connect to socket 'localabstract:/com.emelianov.audio-0/platform-1612197760986.sock': Connection refused
2021-02-01 11:42:59.181 18982-18982/com.emelianov.audio E/RecyclerView: No adapter attached; skipping layout
2021-02-01 11:44:31.678 18982-18982/com.emelianov.audio A/libc: Fatal signal 11 (SIGSEGV), code 0, fault addr 0x4aaf in tid 18982 (emelianov.audio), pid 18982 (emelianov.audio)
2021-02-01 11:44:39.922 18982-18982/com.emelianov.audio A/libc: crash_dump helper failed to exec
2021-02-01 11:44:39.924 18982-18982/com.emelianov.audio A/libc: failed to wait for crash_dump helper: No child processes
2021-02-01 11:44:47.004 1271-1681/? E/InputDispatcher: channel '21319d4 com.emelianov.audio/com.emelianov.audio.activities.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
The weird thing is that whenever I run the app in non-debug mode, everything works fine. Both Realm and the new native library that I am adding work just fine. I'm new to using native libraries in Android, so is it possible that I'm initializing the CMake incorrectly?
Anyway, here's my build.grade and CMakeLists.txt:
build.grade:
buildscript {
repositories {
mavenCentral()
maven {
url "https://jitpack.io"
}
maven {
url "https://maven.google.com"
}
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
classpath "io.realm:realm-gradle-plugin:10.3.1"
}
}
apply plugin: 'com.android.application'
apply plugin: 'realm-android'
def superpowered_sdk_path = new File(projectDir, '../SuperpoweredSDK/Superpowered')
repositories {
mavenCentral()
maven {
url "https://jitpack.io"
}
maven {
url "https://maven.google.com"
}
jcenter()
google()
}
android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "{myapplicationid}"
minSdkVersion 24
targetSdkVersion 29
versionCode 320
versionName "21.151.2"
ndk { // these platforms cover 99.9% percent of all Android devices
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
compileOptions {
incremental false
}
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-19', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_ARM_NEON=TRUE', '-DANDROID_STL=c++_static', "-DPATH_TO_SUPERPOWERED:STRING=${superpowered_sdk_path}"
cFlags '-O3', '-fsigned-char' // full optimization, char data type is signed
cppFlags '-fsigned-char', "-I${superpowered_sdk_path}"
}
}
}
buildTypes {
release {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDir 'libs'
jni.srcDirs = []
}
// Move the tests to tests/java, tests/res, etc...
androidTest.setRoot('tests')
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
ndkVersion '21.3.6528147'
}
dependencies {
... a bunch of dependencies
implementation fileTree(include: '*.jar', dir: 'libs')
... more dependencies
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
allprojects {
repositories {
jcenter()
google()
}
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
# convert SDK path to forward slashes on Windows
file(TO_CMAKE_PATH ${PATH_TO_SUPERPOWERED} PATH_TO_SUPERPOWERED)
#include_directories(src/main/cpp)
include_directories(${PATH_TO_SUPERPOWERED})
# compile player example to a native library
add_library (
PlayerExample
SHARED
jni/PlayerExample.cpp
${PATH_TO_SUPERPOWERED}/OpenSource/SuperpoweredAndroidAudioIO.cpp
)
# link the native library against the following libraries
target_link_libraries (
PlayerExample
log
android
OpenSLES
${PATH_TO_SUPERPOWERED}/libSuperpoweredAndroid${ANDROID_ABI}.a
)
Goal
Add a different native library (not Realm) to my Android project, without breaking Realm when in debug mode.
Actual Results
I have an Android app which uses Realm, and works fine. But when I add a native library to the app (not Realm), then things stop working. It seems that changing my
build.gradle
to specify anexternalNativeBuild
which references CMake causes Realm to break BUT ONLY IN DEBUG MODE.Steps & Code to Reproduce
Steps to reproduce:
1) Integrate Realm to your Android app via maven.
2) Update my build.grade with this (needed for the new library I'm adding):
3) Run the app in debug mode
4) LLDB debugger hits 3 breakpoints, although code is not visible. The error for each of these breakpoints is as follows:
SIGSEGV (signal SIGSEGV: invalid address (fault address: 0x0))
SIGSEGV (signal SIGSEGV: address access protected (fault address: 0xab39bf40))
SIGSEGV (unknown crash reason)
5) Even though I have breakpoints in my Java code, none of them are triggered.
6) The app crashes, and logcat show an exception from those Java lines on which I had breakpoints set in step 5. The failure occurs because I am expecting to find a Realm object which does not exist. It appears that the crash from the LLDB debugger is preventing Realm from working properly, so my Java logic is breaking too.
6) After the crash, looking at the logcat, I also see some failures around the SIGSEGV:
The weird thing is that whenever I run the app in non-debug mode, everything works fine. Both Realm and the new native library that I am adding work just fine. I'm new to using native libraries in Android, so is it possible that I'm initializing the CMake incorrectly?
Anyway, here's my build.grade and CMakeLists.txt:
build.grade:
CMakeLists.txt:
Version of Realm and tooling
Realm version(s): io.realm:realm-gradle-plugin:10.3.1
Realm Sync feature enabled: No
Android Studio version: 4.1.2
Android Build Tools version: 29.0.3
Gradle version: 6.5
Which Android version and device(s): Android version 8.1.0 on an LG Phoenix 4