微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

堆栈跟踪在到达我的代码之前停止在使用NDK的Android上

如何解决堆栈跟踪在到达我的代码之前停止在使用NDK的Android上

| 我正在使用NDK r5b在Android 2.3.x上进行开发。有时我的代码崩溃了,我想知道在哪里。我已经知道如何在有指针的情况下在应用程序中获取相应的行(即来自Android的堆栈跟踪)。 但是,通常我会看到这样的无用堆栈跟踪(完整堆栈跟踪):
     #00  pc 0006561a  /system/lib/egl/libGLESv2_adreno200.so
     #01  pc 0006b900  /system/lib/egl/libGLESv2_adreno200.so
     #02  pc 0005aac8  /system/lib/egl/libGLESv2_adreno200.so
     #03  pc 0001687a  /system/lib/egl/libGLESv1_CM_adreno200.so
     #04  pc 000096ce  /system/lib/egl/libGLESv1_CM_adreno200.so
或这个:
(gdb) bt
#0  0xafd0c51c in epoll_wait () from /Volumes/SecureCode/webos/rta/android/obj/local/armeabi/libc.so
#1  0xa81216a6 in ?? ()
甚至根本不提我的代码。 有没有办法获得比这更好的堆栈跟踪?为什么某些库函数“不透明”,因为它们不允许回溯到调用函数的“透视”,从而导致堆栈跟踪停止? 据我所知,调试此类问题的唯一方法是在程序的每个点使用日志记录和/或使用gdb逐行浏览。 这些Android库的调试版本是否提供了ROM,而不是运行时的ROM,这会有所帮助吗? (我只用一部电话进行开发,所以我不关心保持完整的功能。)(实际上,我注意到上面的
gdb
堆栈跟踪中的
libc.so
路径在我的应用程序目录中。我是否可以将其打包用不同的(调试)
libc.so
,这有帮助吗?) 可能有帮助的最后一件事:在上述从logcat进行的堆栈跟踪(第一个)中,原始堆栈转储中提到了我的库:
stack:
  ...
  ...
  4471cb88  00000028  
  4471cb8c  afd4649c  
  4471cb90  80b4eb71  /data/data/com.audia.dev.rta/lib/librta.so
  4471cb94  00299180  
  ...
  ...
但这不是函数指针。那会是什么,在应用崩溃后会有什么帮助?我猜可能不是堆指针之类的。     

解决方法

           有没有办法获得比这更好的堆栈跟踪? 据我所知,您必须自己构建和编写Android映像。它使您可以拥有Android的完整完整符号(可执行文件和共享库),专有共享库除外。 从源代码构建-从源代码编译CyanogenMod 它还提供了使用gdb使用符号的功能。
$ adb shell setprop debug.db.uid 32767
$ adb forward tcp:5039 tcp:5039

/*
 program terminated and debuggerd caught exception like the following.
 Use the PID number for gdbclient 3rd parameter.
 I/DEBUG   ( 2154): ******************************************************** 
 I/DEBUG   ( 2154): * Process 2508 has been suspended while crashing.  To
 I/DEBUG   ( 2154): * attach gdbserver for a gdb connection on port 5039:
 I/DEBUG   ( 2154): *
 I/DEBUG   ( 2154): *     adb shell gdbserver :5039 --attach 2508 &
 I/DEBUG   ( 2154): *
 I/DEBUG   ( 2154): * Press HOME key to let the process continue crashing.
 I/DEBUG   ( 2154): ********************************************************)
*/

$ gdbclient \"\" \"\" 2508
编辑: 您仍然可以使用ndk-gdb代替gdbclient命令。请指定共享库的符号文件。
(gdb) set solib-search-path (ANDROID_SOURCE_PATH)/out/target/product/(PRODUCT_NAME)/symbols/system/lib
编辑2: 如果不需要Android系统共享库的符号,只需adb拉共享库并为其设置sollib-search-path。
$ adb pull /system/lib lib

$ ndk-gdb
...
(gdb) set solib-search-path lib
    ,        几个注意事项: 在某些情况下,由于堆栈已被部分丢弃,因此堆栈跟踪可能会损坏。虽然不太可能。 您正在使用什么操作系统? Gingerbread(Android 2.3)在堆栈跟踪方面要好得多。如果您未运行Android 2.3,请在某处为您的手机找到Android 2.3 ROM,或者购买运行2.3的廉价开发手机。 您看过Onur的脚本吗?即使对于Android 2.2手机,它对我来说也运行得很好。 希望fadden正在阅读此书,我确信他得到的答案比我的有用。     ,        请检查以下问题:我的gcc C ++应用程序崩溃时如何生成stacktrace 我们使用Android应用程序进行了同样的操作:我们编写了自己的信号处理程序,处理了信号7(sigbus)和信号11(sigsegv),并从处理程序中打印出堆栈记录。 我们虽然没有使用backtrace()函数,但是手动展开堆栈... 结合前两个答案,您应该能够编写自己的信号处理程序以转储堆栈跟踪。本文还可以为您提供帮助:http://www.ibm.com/developerworks/power/library/l-sigdebug/index.html。 请记住,提取寄存器内容取决于体系结构,因此您必须将上述代码中使用的结构替换为android上的结构(取决于ARM处理器)。例如,我不得不深入研究\'struct ucontext \'的Android源代码。 有了堆栈跟踪后,请在输出上运行脚本,该脚本将使用addr2line和未剥离的可执行文件解析符号。     ,        抱歉,我的问题没有答案,但我确实发现,集成Google Breakpad是获得良好堆栈跟踪/崩溃报告的绝佳方法。编写一个调用Breakpad的信号处理程序很容易,它可以处理所有事情。我们只需要将报告上传到我们的服务器即可。我们还将调用ѭ9的过程集成到我们的构建系统中。虽然花了一些工夫,但总的来说,这对于在Android上获得良好的本机崩溃报告来说是完美的。 这个答案有一些关于编写信号处理程序的细节。您所需的其余代码位于Wiki下的Google Breakpad网站上。     ,对于某些堆栈跟踪,我确实得到了这个问题的答案。 (从这个问题看来,可能是我所得到的全部。)这些以
lr
(链接寄存器)地址结尾。看到我的其他问题/答案。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。