Android NDK 抛出信号 sigsegv:调试模式下的无效地址

Rya*_*rey 5 android android-ndk

我最近实施了 android NDK 来隐藏我的应用程序密钥和机密。因为每当我在 android studio 中以调试模式运行我的应用程序时我都会这样做,所以我的断点会被 sigsegv(信号 sigsegv:无效地址(故障地址:0x8))中断。当我的任何进程完全访问 NDK 时,就会发生这种情况。我对正在发生的事情感到困惑,因为我对 NDK 非常陌生。我的 C 代码非常简单,看起来像:

#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");
}
Run Code Online (Sandbox Code Playgroud)

我在我的静态 UtilFuncs 类中访问它,例如:

static {
        System.loadLibrary("keys");
    }

    public static native String getSecretOne();

    public static String getSecret() {
            return getSecretOne();

    }
Run Code Online (Sandbox Code Playgroud)

当我正常运行应用程序时,它运行良好,但由于这些 sigsegv: invalid address 错误出现,当我尝试读取监视变量时,它使调试完全无法使用。任何人之前遇到过这种情况或知道我做错了什么?

更新:更新到 Android 9 的手机不会抛出错误,所以我的问题解决了,但我仍然不知道是什么导致了它。仍然会对有关原始原因的任何理论感兴趣。

gOn*_*nZo 8

当我遇到相同的情况时,我发现了这个线程:添加 NDK 代码后,在 Android Studio (v3.2.1) 调试器中运行我的应用程序时出现 SIGSEGV 错误。在没有调试器的情况下运行它会正常执行。

我还没有找到解决方案,但是我找到了进一步的线索。

在调试器捕获 SIGSEGV 故障后,打开断点对话框。 在此处输入图片说明

这在“libart.so: art_sigsegv_fault”处显示了一个活动断点:

在此处输入图片说明

libart 中似乎有一些 sigsegv 故障的历史。我没有找到任何解决办法。但是,禁用此断点确实允许我继续调试我的应用程序(一种变通方法)。


小智 1

以下是我通过过去必须解决的 JNI 崩溃创建的一小部分需要检查的内容。

  • 您使用的是 C 本机代码吗?不是C++吗?检查一切是否一致。文件扩展名应该是 .c,如果有的话请检查声明文件。Android NDK 文档的“JNI 技巧”中有一小节是关于它的(JavaVM 和 JNIEnv 部分)。
  • 您确定使用NewStringUTF字符串作为参数的方式吗?检查同一Android NDK 文档的“UTF-8 和 UTF-16 字符串”部分。
  • 在您的情况下,故障地址的值较低。检查有关本机崩溃的 Android 文档的“诊断本机崩溃”一章中的“低地址空指针取消引用”部分。
  • 您是否尝试将所有内容都放入 C++ 中?我正在使用类似的功能,如果您想尝试:

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);
}
Run Code Online (Sandbox Code Playgroud)