Reputation: 211
I implemented the android NDK recently to hide my app keys and secrets. Since I did that whenever I run my app in debug mode in android studio, my breakpoints get interrupted with sigsegv (signal sigsegv: invalid address (fault address: 0x8)). This occurs when any of my processes access the NDK at all. I'm baffled as to what's happening as I am very new with the NDK. My C code is extremely simple, and looks something like:
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_my_company_co_utilities_UtilFuncs_getSecretOne(JNIEnv *env, jobject instance) {
return (*env)-> NewStringUTF(env, "my_secret_1");
}
JNIEXPORT jstring JNICALL
Java_com_my_company_co_utilities_UtilFuncs_getSecretTwo(JNIEnv *env, jobject instance) {
return (*env)-> NewStringUTF(env, "my_secret_2");
}
JNIEXPORT jstring JNICALL
JJava_com_my_company_co_utilities_UtilFuncs_getKeyOne(JNIEnv *env, jobject instance) {
return (*env)-> NewStringUTF(env, "my_key_1");
}
JNIEXPORT jstring JNICALL
Java_com_my_company_co_utilities_UtilFuncs_getKeyTwo(JNIEnv *env, jobject instance) {
return (*env)->NewStringUTF(env, "my_key_2");
}
and I access it in my static UtilFuncs class like:
static {
System.loadLibrary("keys");
}
public static native String getSecretOne();
public static String getSecret() {
return getSecretOne();
}
It works perfectly when I run the app normally, but it has made debug unusable entirely because of these sigsegv: invalid address errors coming up when I'm trying to read watch variables. Anyone encounter this before or have any idea what I'm doing wrong?
Update: The error is not thrown on phones updated to Android 9, so my problem is resolved, but I still have no idea what was causing it in the first place. Would still be interested in any theories on the original cause.
Upvotes: 5
Views: 11280
Reputation: 666
In case anyone else experiences this more recently (Oct 2020 Android Studio 4.0.1 NDK 19.2.5345600):
I get the same crash under similar circumstances but only when I pass a parameter into the native method such as a jstring and only on an x86 emulator.
For example, the following code on an x86 API 30 emulator crashes as soon as it hits a breakpoint but otherwise runs fine:
extern "C" JNIEXPORT jstring JNICALL
Java_some_package_SomeClass_someMethod(
JNIEnv* env,
jobject /* this */,
jstring foo) {
// anything ...
}
I can however debug this code with breakpoints no problem on an x86_64 emulator or on a physical device. So the solution is to use an x86_64 AVD or always debug on device.
Upvotes: 2
Reputation: 51
If you sure your C code always work fine, maybe you want to ignore error like this and debug in java. Change "Debug Configuration"-"Debug Type" from any to "Java Only"
Upvotes: 5
Reputation: 6736
It's not a solution!
I think that you should stick with @NoonanRosenblum asnwer and try to find the real cause of it in your NDK and fix it.
But if you don't have time for that you can just comment out a call for CMake in your module gradle build file:
buildTypes {
...
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}
buildTypes {
...
// externalNativeBuild {
// cmake {
// path "src/main/cpp/CMakeLists.txt"
// }
}
}
Don't forget that if you call a native method it will crash, so use it only if you want to debug step-by-step and you don't want to skip that annoying native crash breakpoints.
Upvotes: 0
Reputation: 489
I discovered this thread when I experience the same: a SIGSEGV fault when running my app in the Android Studio (v3.2.1) debugger after adding NDK code. Running it without the debugger executes normally.
I have not found a solution, however I found a further clue.
After the debugger traps the SIGSEGV fault, open the breakpoints dialog.
This shows an active breakpoint at 'libart.so: art_sigsegv_fault':
There appears to be some history of sigsegv faults in libart. I did not find any resolution. However, disabling this breakpoint did allow me to continue to debug my application (a work-around).
Upvotes: 13
Reputation: 533
Here is a small list of things to check I created through past JNI crashes I had to solve.
NewStringUTF
, using a string as argument this way ? Check the section "UTF-8 and UTF-16 strings" of the same Android NDK documentation.myNativeLib.cpp
extern "C"
JNIEXPORT jstring
JNICALL Java_com_my_company_co_utilities_UtilFuncs_getSecretOne(
JNIEnv *env
,jobject /* this */
)
{
unsigned char my_secret_1[] = {0x1a, 0xb2, 0xb7, 0x39, 0x00, 0x20, 0xb1, 0x0a, 0x33};
return env->NewStringUTF(my_secret_1);
}
Upvotes: 1