Ryan McCaffrey
Ryan McCaffrey

Reputation: 211

Android NDK throwing signal sigsegv: invalid address in debug mode

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

Answers (5)

Philip
Philip

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

YC Wong
YC Wong

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"

guide

Upvotes: 5

Kirill Karmazin
Kirill Karmazin

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

gOnZo
gOnZo

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. enter image description here

This shows an active breakpoint at 'libart.so: art_sigsegv_fault':

enter image description here

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

NoonanRosenblum
NoonanRosenblum

Reputation: 533

Here is a small list of things to check I created through past JNI crashes I had to solve.

  • You are using C native code right? Not C++? Check that everything is coherent. The file extension should be .c, and check declaration files if you have some. The "JNI tips" of Android NDK documentation has a small section about it (section JavaVM and JNIEnv).
  • Are you sure about the way you use NewStringUTF, using a string as argument this way ? Check the section "UTF-8 and UTF-16 strings" of the same Android NDK documentation.
  • In your case the fault address is a low value. Check the "Low-address null pointer dereference" section of the chapter "Diagnosing Native Crashes" of the Android documentation on native crash.
  • Did you try to put all in C++ ? I am using similar functions, if you wish to try :

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

Related Questions