Android ARM C++ 异常调试
Android ARM C++ exception debugging
我有我的程序的回溯栈(运行 在 Android ARM 上),像这样:
#00 pc 0001d796 /system/lib/libc.so (abort+57) [armeabi-v7a]
#01 pc 0004f663 libxx.so (__gnu_cxx::__verbose_terminate_handler()+226) [armeabi-v7a]
#02 pc 00024709 libxx.so (__cxxabiv1::__terminate(void (*)())+4) [armeabi-v7a]
#03 pc 0002477d libxx.so (std::terminate()+8) [armeabi-v7a]
#04 pc 0058f3d3 libxxx_sdk.so [armeabi-v7a]
#05 pc 00065ac7 /system/lib/libc.so (__pthread_start(void*)+22) [armeabi-v7a]
#06 pc 0001e9ad /system/lib/libc.so (__start_thread+32) [armeabi-v7a]
这可能是异常引起的,但我无法在 libxxx_sdk.so
中找到正确的地方引发了这个异常。
那么,我能做些什么来让回溯对我找出正确的问题更有价值吗?
注:
- 我没有核心转储文件,系统只报告回溯信息。
- 此问题不会在本地重现。
- 当程序 运行 在用户 Android phone.
上时很少发生此问题
更新 1
我用objdump -Cd
转储了libxxx_sdk.so
,找到了0058f3d3
附近的地址,但还是不知道是谁调用了下面的__pointer_catch
:
0055c290 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const>:
~~~
...
~~~
58f3c0: e7d7 b.n 58f372 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x330e2>
58f3c2: 2901 cmp r1, #1
58f3c4: d103 bne.n 58f3ce <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x3313e>
58f3c6: f7ed e486 blx 17ccd4 <__cxa_begin_catch@plt>
58f3ca: f7ed e73c blx 17d244 <__cxa_rethrow@plt>
58f3ce: f7ed e482 blx 17ccd4 <__cxa_begin_catch@plt>
58f3d2: f7ee e136 blx 17d640 <std::terminate()@plt>
58f3d6: f7ed e484 blx 17cce0 <__cxa_end_catch@plt>
58f3da: b114 cbz r4, 58f3e2 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x33152>
58f3dc: 4620 mov r0, r4
...
~~~
谢谢!
I can't figure out the right place in libxxx_sdk.so
堆栈跟踪表明 libxxx_sdk.so
已完全剥离。 如果您希望能够调试它,请不要那样做。
为了确定 libxxx_sdk.so
中与地址 0x058f3d3
相对应的位置,您需要知道该库的加载地址。由于您目前没有该信息,您可能希望将日志记录添加到库中,这样每次加载它时,您都会在其中记录一些函数的地址(我们称之为 fn
)。下次它崩溃时,您将能够从崩溃地址中减去 &fn
的记录值,并从 nm libxxx_sdk.so
输出中添加 &fn
,以获得崩溃函数的地址。
或者,您可以检查 libxxx_sdk.so
中以 0x3d3
结尾的地址处的每条指令,以找到调用 __throw
的指令。如果只有一条这样的指令,则可能是抛出异常的那条指令。
我有我的程序的回溯栈(运行 在 Android ARM 上),像这样:
#00 pc 0001d796 /system/lib/libc.so (abort+57) [armeabi-v7a]
#01 pc 0004f663 libxx.so (__gnu_cxx::__verbose_terminate_handler()+226) [armeabi-v7a]
#02 pc 00024709 libxx.so (__cxxabiv1::__terminate(void (*)())+4) [armeabi-v7a]
#03 pc 0002477d libxx.so (std::terminate()+8) [armeabi-v7a]
#04 pc 0058f3d3 libxxx_sdk.so [armeabi-v7a]
#05 pc 00065ac7 /system/lib/libc.so (__pthread_start(void*)+22) [armeabi-v7a]
#06 pc 0001e9ad /system/lib/libc.so (__start_thread+32) [armeabi-v7a]
这可能是异常引起的,但我无法在 libxxx_sdk.so
中找到正确的地方引发了这个异常。
那么,我能做些什么来让回溯对我找出正确的问题更有价值吗?
注:
- 我没有核心转储文件,系统只报告回溯信息。
- 此问题不会在本地重现。
- 当程序 运行 在用户 Android phone. 上时很少发生此问题
更新 1
我用objdump -Cd
转储了libxxx_sdk.so
,找到了0058f3d3
附近的地址,但还是不知道是谁调用了下面的__pointer_catch
:
0055c290 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const>:
~~~
...
~~~
58f3c0: e7d7 b.n 58f372 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x330e2>
58f3c2: 2901 cmp r1, #1
58f3c4: d103 bne.n 58f3ce <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x3313e>
58f3c6: f7ed e486 blx 17ccd4 <__cxa_begin_catch@plt>
58f3ca: f7ed e73c blx 17d244 <__cxa_rethrow@plt>
58f3ce: f7ed e482 blx 17ccd4 <__cxa_begin_catch@plt>
58f3d2: f7ee e136 blx 17d640 <std::terminate()@plt>
58f3d6: f7ed e484 blx 17cce0 <__cxa_end_catch@plt>
58f3da: b114 cbz r4, 58f3e2 <__cxxabiv1::__pointer_type_info::__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const+0x33152>
58f3dc: 4620 mov r0, r4
...
~~~
谢谢!
I can't figure out the right place in libxxx_sdk.so
堆栈跟踪表明 libxxx_sdk.so
已完全剥离。 如果您希望能够调试它,请不要那样做。
为了确定 libxxx_sdk.so
中与地址 0x058f3d3
相对应的位置,您需要知道该库的加载地址。由于您目前没有该信息,您可能希望将日志记录添加到库中,这样每次加载它时,您都会在其中记录一些函数的地址(我们称之为 fn
)。下次它崩溃时,您将能够从崩溃地址中减去 &fn
的记录值,并从 nm libxxx_sdk.so
输出中添加 &fn
,以获得崩溃函数的地址。
或者,您可以检查 libxxx_sdk.so
中以 0x3d3
结尾的地址处的每条指令,以找到调用 __throw
的指令。如果只有一条这样的指令,则可能是抛出异常的那条指令。