You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio调试接收jstring的NDK原生方法时触发art_sigsegv_fault

Android Studio调试NDK接收jstring参数函数触发art_sigsegv_fault问题

问题描述

在Android Studio中调试NDK代码时,若在接收jstring参数的原生函数内设置断点,会立刻触发art_sigsegv_fault错误,应用直接运行完全正常,仅调试时复现。

复现用最简代码

Java层代码(MainActivity.java)

package com.example.ndktestapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        testFoo(5);
        testBar("/tmp/");
    }

    static native void testFoo(int x);
    static native void testBar(String path);

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

NDK层代码(NDKTestApp.cpp)

#include <jni.h>
#include <android/log.h>

extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndktestapp_MainActivity_testFoo(JNIEnv *env, jclass cls, jint x)
{
    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "This is foo");
    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "foo x = %d", x);
    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "foo EXIT");
}

extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndktestapp_MainActivity_testBar(JNIEnv *env, jclass cls, jstring tmpPath)
{
    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "This is Bar");

    auto nativeChars = env->GetStringUTFChars(tmpPath, 0);

    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "Bar path = %s", nativeChars);

    env->ReleaseStringUTFChars(tmpPath, nativeChars);

    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "Bar EXIT");
}

问题细节

  • 接收jint类型参数的testFoo(int)函数可正常设置断点、单步调试,无任何异常
  • 接收jstring类型参数的testBar(String)函数断点命中时会立刻崩溃,崩溃栈如下:
art_sigsegv_fault 0x00000000e3785bf0
art::FaultManager::HandleFault(int, siginfo*, void*) 0x00000000e37861a4
art::art_fault_handler(int, siginfo*, void*) (.llvm.6299116872343706859) 0x00000000e3785ebb
art::SignalChain::Handler(int, siginfo*, void*) 0x000000005cef31ae
__restore_rt 0x00000000e5560bc0
art::Thread::DecodeJObject(_jobject*) const 0x00000000e3bb121a
<unknown> 0x00000000e595e06d
<unknown> 0x000000005cef1170
art_quick_generic_jni_trampoline 0x00000000e364b133
art_quick_invoke_static_stub 0x00000000e3644af3
art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x00000000e36d9393
art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*) 0x00000000e388f702
bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000e3883a3f
void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000e3656201
ExecuteSwitchImplAsm 0x00000000e364bde3
art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.16375758241455872412) 0x00000000e3878c82
art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x00000000e3882c20
bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x00000000e3883a21
void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x00000000e3657e4f
ExecuteSwitchImplAsm 0x00000000e364bde3
...

临时规避方案

可以在testBar()内部调用不涉及JNI参数的自定义函数,单步调试该自定义函数时无异常,仅返回testBar()时会触发错误,可基于该特性实现临时调试:

static void
notNdk(const char *str)
{
    __android_log_print(ANDROID_LOG_INFO, "NDKTest", "notNdk received %s", str);
}

内容的提问来源于stack exchange,提问作者Edward Falk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:06:03