编译
编译选项中需要有 -g选项,可以与-O2… 同时存在
例如生成测试文件test
$ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 4.1.0, not stripped
表明test是一个没有strip过的文件,包含有调试符号
查看符号表及代码地址
查看执行程序的符号表
$ arm-ca53-linux-gnueabihf-nm test
U abort@@GLIBC_2.4
U __aeabi_unwind_cpp_pr0@@GCC_3.5
00021048 B __bss_end__
00021048 B _bss_end__
00021044 B __bss_start
00021044 B __bss_start__
00010830 t call_weak_fn
00021044 b completed.10368
00010694 T main
.....
显示执行程序的汇编信息,其中第一列为后面addr2line将要用到的地址
$ arm-ca53-linux-gnueabihf-objdump -d test
Disassembly of section .text:
00010694 <main>:
10694: e92d47f0 push {r4, r5, r6, r7, r8, r9, sl, lr}
10698: e3045b40 movw r5, #19264 ; 0x4b40
1069c: e340504c movt r5, #76 ; 0x4c
106a0: e59f4128 ldr r4, [pc, #296] ; 107d0 <main+0x13c>
106a4: e24dd0a8 sub sp, sp, #168 ; 0xa8
106a8: e59f7124 ldr r7, [pc, #292] ; 107d4 <main+0x140>
106ac: e3a09f4b mov r9, #300 ; 0x12c
106b0: e08f4004 add r4, pc, r4
106b4: e28d6008 add r6, sp, #8
106b8: e08f7007 add r7, pc, r7
106bc: e28d8050 add r8, sp, #80 ; 0x50
106c0: e28da004 add sl, sp, #4
106c4: e1a00005 mov r0, r5
106c8: ebffffdc bl 10640 <usleep@plt>
106cc: e1a01006 mov r1, r6
106d0: e1a00004 mov r0, r4
106d4: ebffffd3 bl 10628 <statvfs@plt>
106d8: e3500000 cmp r0, #0
106dc: 1a000011 bne 10728 <main+0x94>
106e0: e59d2008 ldr r2, [sp, #8]
106e4: e3a01000 mov r1, #0
106e8: e59d3010 ldr r3, [sp, #16]
106ec: e3e00103 mvn r0, #-1073741824 ; 0xc0000000
106f0: e0832392 umull r2, r3, r2, r3
106f4: e1530001 cmp r3, r1
使用addr2line查地址对应的代码
$ arm-ca53-linux-gnueabihf-addr2line -Cfe test
106d8
main
/home/test/test.cpp:19
注意64位的库,需要使用64位的addr2line
aarch64-linux-android-addr2line
打印堆栈
参考Android的 debuggerd/libbacktrace和开源的libunwind
使用命令debuggerd pgrep test
打印堆栈如下
···
$ debuggerd 580
I 2019-12-31 09:16:00.448786 [800]/Backtrace:
----- pid 580 at 2019-12-31 09:16:00 -----
I 2019-12-31 09:16:00.449454 [800]/Backtrace: Cmd line: test
D 2019-12-31 09:16:00.449744 [800]/Backtrace: “test” sysTid=580
I 2019-12-31 09:16:00.478072 [800]/Backtrace: #00 pc 000992d0 /lib/libc-2.26.so (nanosleep+28)
I 2019-12-31 09:16:00.478704 [800]/Backtrace: #01 pc 000c6d60 /lib/libc-2.26.so (usleep+68)
I 2019-12-31 09:16:00.478810 [800]/Backtrace: #02 pc 00000804 /bin/test (_init+504)
I 2019-12-31 09:16:00.478889 [800]/Backtrace: #03 pc 00016b1c /lib/libc-2.26.so (__libc_start_main+276)
I 2019-12-31 09:16:00.478962 [800]/Backtrace: #04 pc 000006e8 /bin/test (_init+220)
I 2019-12-31 09:16:00.479068 [800]/Backtrace: dump_thread exit
I 2019-12-31 09:16:00.479485 [800]/Backtrace:
···
查找对应代码
正常的话,使用toolchain中的addr2line -Cfe xxx crashaddr
可以得到对应的代码行数
debug遇到的问题
进程处于T状态,即STOP状态,可以发送信号SIGCONT恢复执行状态
kill -s SIGCONT 578
FIXME:貌似执行程序是直接加载到对应的地址的,不需要减去map当中的便宜地址,否则addr2line会找不到代码