从本机线程获取Android上的回溯?

时间:2014-07-17 15:03:23

标签: android multithreading android-ndk stack-trace

我正在开发一个原本不属于我自己的代码库(Parrot的开源ARDrone库)。我已经删除了不必要的线程并将崩溃隔离到特定线程,即负责从无人机传输视频数据包的人[Parrot ARDrone 2.0]。

我已将无人机从TCP视频输出更改为不同端口上的UDP。当我加载Android应用程序[AR.Freeflight 2]时,视频流平滑了一段时间,但应用程序普遍崩溃与致命的SIGBUS在非常长而复杂的视频管道中执行的某处。崩溃需要20秒到15分钟。

我在相关线程上设置了信号处理程序,可以成功捕获信号。我经历了将视频输入线程附加到JVM的过程,并且我能够使用缓存的全局引用来查找具有静态方法的Java类,该方法用于打印当前线程的callstack(我已经使用抛出一个新的RuntimeException并使用Thread.dumpStack())。我经历这个艰难过程的原因是因为作为NDK一部分的仿生版本没有本机backtrace()函数,我应该可以直接从信号处理程序调用;看来这个方法已经在stackoverflow的其他地方展示,如果你仍然在Java生成的线程中,它可以很好地跟踪整个C callstack 。但是,在我的应用程序中, only 调用显示为在我的静态void trace-printing函数之前发生的

dalvik.system.NativeStart.run(Native Method)

因此,我不知道如何获取我的android应用程序的调用堆栈以找到此崩溃的真实位置,因为Java将在线程的第一次Java调用之前发生的所有事情视为“一个大blob” C“。有没有人有办法解决这个问题?

更新:我设法从我的信号处理程序的void * final参数中提取特定于android的sigcontext对象,这意味着我现在在信号发生之前有指令指针和堆栈指针。在这种情况下,有没有人知道如何调用_Unwind_Backtrace从那里回溯调用堆栈,而不是从信号处理程序本身展开?

1 个答案:

答案 0 :(得分:1)

当应用程序在本机代码中崩溃时,您实际上会记录回溯。崩溃后直接adb logcat -d > crash.log。此崩溃日志不包含任何符号,但NDK附带工具ndk-stack

ndk-stack -sym <path> [-dump <path>]

   -sym  Contains full path to the root directory for symbols.
   -dump Contains full path to the file containing the crash dump.
         This is an optional parameter. If ommited, ndk-stack will
         read input data from stdin

See docs/NDK-STACK.html in your NDK installation tree for more details.

如果链接的.so文件没有被剥离的符号,这将提供可读的堆栈跟踪。