在安卓 NDK 上获取堆栈跟踪
Getting stack trace on Android NDK
首先:这个问题已经被问了几次,有些答案很有用,但没有一个提供可行的解决方案。我首先尝试了这个答案中的代码。令人惊讶的是,它确实做了它的事情,但存在一个巨大的问题:我能想到的调用此代码的唯一方法是SIGSEGV
处理程序,并且它有自己的堆栈 - 因此我无法像那样获得我崩溃的应用程序的实际堆栈。
然后,我尝试合并这个答案。它稍微好一点 - 它产生堆栈的第一项(发生崩溃的方法)。但那是在 - 没有实际的回溯。因此,一旦崩溃发生在第三方库(或标准库)内,此信息就毫无意义。
如何进一步改进代码并最终获取我糟糕的崩溃应用程序的堆栈跟踪?
P. S. 在 Android 4.0.3 和 Android 5.0 上测试,到目前为止行为是相同的。我想至少支持 5.0 和最近的先前版本,如 4.3-4.4。
你试过咖啡库吗?
它是一个 JNI 信号捕获器,允许将 SIGSEGV(+) 信号转换为具有混合 jni/java 回溯的 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)
堆栈跟踪的本机 (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
相关文章:
- 如何从 x64 程序集中的堆栈中获取参数?
- 无法获取已填充堆栈<char>的顶部元素
- 如何获取崩溃的DLL的堆栈跟踪?
- 为什么我不能将从我的 BST 获取的这个节点推送到这个堆栈中?
- 如何获取 systemc 线程的堆栈大小
- 使用 gdb 时无法获取堆栈跟踪
- 重载时获取堆栈溢出 >> 运算符函数是为类调用的。我需要进行哪些更改?
- <int> 在不破坏堆栈的情况下获取 C++ 中的堆栈总和
- C 获取器和设定器替代Visual Studio上的呼叫堆栈
- 是否有一种便携式/标准的方法可以在堆栈跟踪中获取文件名和亚麻布
- 如何使用 Win32 API 获取任何线程的堆栈大小和堆栈限制
- 处理POSIX信号:如何在不使用BackTrace_symbols的情况下获取堆栈跟踪
- 无法在 Windows 中获取调用堆栈
- 获取包含共享库的c++应用程序的调用堆栈
- 在安卓 NDK 上获取堆栈跟踪
- 在VB6中获取堆栈跟踪
- 如何在Netbeans C++IDE中获取堆栈跟踪
- 如何获取堆栈跟踪信息
- SymFromAddr 返回ERROR_INVALID_ADDRESS标志,如何在 mingw 中获取堆栈跟踪
- 调用mysql_close获取堆栈损坏,这是MySQL中的一个bug吗?