在Android NDK上获取堆栈跟踪

首先:这个问题已经被问了几次,有些答案是有用的,但是没有一个提供一个工作的解决scheme。 我开始尝试从这个答案的代码。 令人惊讶的是,它做到了这一点,但是有一个很大的问题:调用这个代码的唯一方法就是SIGSEGV处理程序,它有自己的堆栈 – 因此我无法得到实际的崩溃应用程序堆栈,就像那。

然后,我试着合并这个答案 。 它稍微好一点 – 它产生堆栈的第一个项目(发生崩溃的方法)。 但是,这是在 – 没有实际的回溯。 所以一旦在第三方库(或标准库)内发生崩溃,这个信息就没有意义了。

我怎样才能进一步改善代码,并最终得到我的可怜的应用程序的堆栈跟踪?

PS在Android 4.0.3和Android 5.0上testing,到目前为止行为是一样的。 我想要支持至less5.0和最近以前的版本,如4.3-4.4。

你尝试咖啡厅图书馆吗?

它是一个JNI信号捕捉器,它允许将SIGSEGV(+)信号转换成java异常,并带有混合的jni / java回溯。 它适用于API-19,但是我没有机会在API> 19上进行测试。 它提供了可以传递给addr2line的程序地址,以便获得对源的最终引用。

代码模板:

 #include "coffeejni.h" #include "coffeecatch.h" void MyClass::foo(JNIEnv *env, int arg1, int arg2) { .... int rc; COFFEE_TRY_JNI(env, rc = crashInside(arg1, arg2)); .... } 

跟踪示例:

 F/myapp (24535): "DESIGN ERROR": thread=t1 F/myapp (24535): java.lang.Error: signal 11 (Address not mapped to object) at address 0xdeadbaad [at libc.so:0x18282] F/myapp (24535): at com.example.NativeSupport.nsc(Native Method) F/myapp (24535): at com.example.NativeSupport.nsc_quiet(NativeSupport.java:328) F/myapp (24535): at com.example.NativeSupport.loop(NativeSupport.java:287) F/myapp (24535): at com.example.NativeSupport.access$2(NativeSupport.java:274) F/myapp (24535): at com.example.NativeSupport$2.run(NativeSupport.java:124) F/myapp (24535): at java.lang.Thread.run(Thread.java:856) F/myapp (24535): Caused by: java.lang.Error: signal 11 (Address not mapped to object) at address 0xdeadbaad [at libc.so:0x18282] F/myapp (24535): at system.lib.libc_so.0x18282(Native Method) F/myapp (24535): at system.lib.libc_so.0xdc04(abort:0x4:0) F/myapp (24535): at data.data.example.lib.libexample_so.0xf147(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x12d1b(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x1347b(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x13969(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x13ab3(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x17a9b(Native Method) F/myapp (24535): at system.lib.libdvm_so.0x1f4b0(dvmPlatformInvoke:0x70:0) F/myapp (24535): at system.lib.libdvm_so.0x4dfa5(dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*):0x164:0) F/myapp (24535): at system.lib.libdvm_so.0x28920(Native Method) F/myapp (24535): at system.lib.libdvm_so.0x2d0b0(dvmInterpret(Thread*, Method const*, JValue*):0xb4:0) F/myapp (24535): at system.lib.libdvm_so.0x5f599(dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list):0x110:0) F/myapp (24535): at system.lib.libdvm_so.0x5f5c3(dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...):0x14:0) F/myapp (24535): at system.lib.libdvm_so.0x549eb(Native Method) F/myapp (24535): at system.lib.libc_so.0x12dd0(__thread_entry:0x30:0) F/myapp (24535): at system.lib.libc_so.0x12534(pthread_create:0xac:0) 

Native(jni)堆栈跟踪的一部分是:

 F/myapp (24535): at data.data.example.lib.libexample_so.0xf147(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x12d1b(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x1347b(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x13969(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x13ab3(Native Method) F/myapp (24535): at data.data.example.lib.libexample_so.0x17a9b(Native Method) 

最后得到一个人形可读的回溯:

 cd android-ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin ./arm-linux-androideabi-addr2line -e /home/joe/myproj/obj/local/armeabi-v7a/libexample.so 0xf147 0x12d1b 0x1347b 0x13969 0x13ab3 0x17a9b