使用addr2line 打印调用栈信息调试程序崩溃

首先参考:https://blog.csdn.net/gongmin856/article/details/79192259

接下来是我复制下来的代码,命名ttt.c

几个命令:

/opt/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -g -rdynamic -funwind-tables -fasynchronous-unwind-tables ttt.c -o test_ttt

注:

  -rdynamic  该参数是链接选项,不是编译选项。这主要是对可执行程序(elf)而言的,而编译动态库时,即使没有rdynamic选项,默认也会将非静态函数放入动态符号表中(刻意隐藏的函数除外)。默认情况下,可执行程序(非动态库)文件内我们定义的非静态函数,是不放到动态符号表中的,链接时只有加上"-rdynamic"才能将所有非静态函数加到动态符号表中。这个参数很多文章里都有写。

-funwind-tables -fasynchronous-unwind-tables:这几个参数比较恶心,很多文章里都没提到,其实很重要,作用是为了backtrace这个函数,如果不加这几个参数,那么backtrace函数会返回1,那么程序test_ttt运行时的栈回溯信息里就只有一个了,如下:

=========>>>catch signal 11 <<<=========

Dump stack start...

backtrace() returned 6 addresses

[00] /mnt/usr/zc/temp/RB1/test_ttt(dump+0x14) [0x400be8] //就会仅仅只有这一行了

[01] /mnt/usr/zc/temp/RB1/test_ttt(signal_handler+0x2c) [0x400cb8]

[02] linux-vdso.so.1(__kernel_rt_sigreturn+0) [0x7f9234a270]

[03] /mnt/usr/zc/temp/RB1/test_ttt(divide+0x34) [0x400bb0]

[04] /mnt/usr/zc/temp/RB1/test_ttt(main+0xc0) [0x400da4]

[05] /lib/libc.so.6(__libc_start_main+0xe4) [0x7f921f3824]

Dump stack end...

在使用addr2line查问题的时候就是看0x400bb0这个值了

/opt/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-addr2line -e ~/smba_share/nfs/temp/RB1/test_ttt 0x400bb0

定位行数:

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:18

如果此时使用objdump方法:

/opt/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-objdump -S -l ~/smba_share/nfs/temp/RB1/test_ttt > info.txt

注:

-l --line-numbers

  用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。

-S --source

  尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。

由上面可以看出问题发生在divide函数里,打开info.txt文件,从下往上看

0000000000400b7c <divide>: //0x400b7c + 0X34 = 0x400bb0

divide():

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:9

#include /* for backtrace() */

#define BACKTRACE_SIZE 16

int divide(int num)

{

400b7c:a9bd7bfd stpx29, x30, [sp, #-48]!

400b80:910003fd movx29, sp

400b84:b9001fa0 strw0, [x29, #28]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:10

int ret = 0x00;

400b88:b9002fbf strwzr, [x29, #44]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:11

int *pTemp = NULL;

400b8c:f90013bf strxzr, [x29, #32]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:13

if(0 != num)

400b90:b9401fa0 ldrw0, [x29, #28]

400b94:7100001f cmpw0, #0x0

400b98:54000080 b.eq400ba8 // b.none

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:15

{

printf("num is not 0 !\n");

400b9c:90000000 adrpx0, 400000 <_init-0x988>

400ba0:91398000 addx0, x0, #0xe60

400ba4:97ffffa7 bl400a40

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:18 //行数和addr2line查出来的一致

}

*pTemp = 0x01; /* 这将导致一个段错误,致使程序崩溃退出 */

400ba8:f94013a0 ldrx0, [x29, #32]

400bac:52800021 movw1, #0x1 // #1

400bb0:b9000001 strw1, [x0]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:20

ret = num + *pTemp;

400bb4:f94013a0 ldrx0, [x29, #32]

400bb8:b9400000 ldrw0, [x0]

400bbc:b9401fa1 ldrw1, [x29, #28]

400bc0:0b000020 addw0, w1, w0

400bc4:b9002fa0 strw0, [x29, #44]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:22

return ret;

400bc8:b9402fa0 ldrw0, [x29, #44]

/home/zhaocan/smba_share/nfs/temp/RB1/ttt.c:25

return 0;

}

你可能感兴趣的:(linux)