当前位置: 技术问答>linux和unix
求addr2line原理
来源: 互联网 发布时间:2016-12-18
本文导语: addr2line非常强大,因而我想了解一下addr2line原理 希望大家可以贴一下原理或给源码地址也行 | addr2line隶属于binutils,是交叉编译工具里比较重要的一个命令: 源代码在: http://download.chinaunix.n...
addr2line非常强大,因而我想了解一下addr2line原理
希望大家可以贴一下原理或给源码地址也行
希望大家可以贴一下原理或给源码地址也行
|
addr2line隶属于binutils,是交叉编译工具里比较重要的一个命令:
源代码在:
http://download.chinaunix.net/download/0001000/900.shtml
binutils-2.15.94-20050118-1-src.tar.gz
个人理解,它还是像objdump一样,读出elf文件的文件头里的符号表,
比如 objdump -t ./test| grep text
0000000000400500 l d .text 0000000000000000 .text
000000000040052c l F .text 0000000000000000 call_gmon_start
0000000000400550 l F .text 0000000000000000 __do_global_dtors_aux
00000000004005c0 l F .text 0000000000000000 frame_dummy
00000000004006a0 l F .text 0000000000000000 __do_global_ctors_aux
0000000000400600 g F .text 0000000000000002 __libc_csu_fini
0000000000400500 g F .text 0000000000000000 _start
0000000000400610 g F .text 0000000000000089 __libc_csu_init
00000000004005ec g F .text 0000000000000012 main
第一项是这个函数在文件的起始地址,第5项是大小,
所以给定一个正文区的地址,它总能算出它是那个函数地址区间里的。
希望这样能使你明白。
源代码在:
http://download.chinaunix.net/download/0001000/900.shtml
binutils-2.15.94-20050118-1-src.tar.gz
个人理解,它还是像objdump一样,读出elf文件的文件头里的符号表,
比如 objdump -t ./test| grep text
0000000000400500 l d .text 0000000000000000 .text
000000000040052c l F .text 0000000000000000 call_gmon_start
0000000000400550 l F .text 0000000000000000 __do_global_dtors_aux
00000000004005c0 l F .text 0000000000000000 frame_dummy
00000000004006a0 l F .text 0000000000000000 __do_global_ctors_aux
0000000000400600 g F .text 0000000000000002 __libc_csu_fini
0000000000400500 g F .text 0000000000000000 _start
0000000000400610 g F .text 0000000000000089 __libc_csu_init
00000000004005ec g F .text 0000000000000012 main
第一项是这个函数在文件的起始地址,第5项是大小,
所以给定一个正文区的地址,它总能算出它是那个函数地址区间里的。
希望这样能使你明白。
|
因为你用-g选项生成的可执行文件,最终的elf文件多生成了几个段,
可以使用 readelf --sections a.out 看的出来
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubtypes 00000000 .debug_pubtypes
.debug_line 这个段里面就包含了每条汇编指令的地址和对应的源代码行数,源代码名字等信息,
使用readelf -wl a.out 命令就可以查看这个段的内容,比如
readelf -wl a.out
Raw dump of debug contents of section .debug_line:
Offset: 0x0
Length: 277
DWARF Version: 2
Prologue Length: 29
Minimum Instruction Length: 1
Initial value of 'is_stmt': 1
Line Base: -5
Line Range: 14
Opcode Base: 13
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 args
Opcode 3 has 1 args
Opcode 4 has 1 args
Opcode 5 has 1 args
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 args
Opcode 10 has 0 args
Opcode 11 has 0 args
Opcode 12 has 1 args
The Directory Table is empty.
The File Name Table:
Entry Dir Time Size Name
1 0 0 0 main.c //////////////这个是文件名
Line Number Statements:
Extended opcode 2: set Address to 0x8048444
Advance Line by 12 to 13
Copy
Special opcode 90: advance Address by 6 to 0x804844a and Line by 1 to 14
Special opcode 202: advance Address by 14 to 0x8048458 and Line by 1 to 15
Special opcode 174: advance Address by 12 to 0x8048464 and Line by 1 to 16
Special opcode 90: advance Address by 6 to 0x804846a and Line by 1 to 17
Special opcode 132: advance Address by 9 to 0x8048473 and Line by 1 to 18
Advance PC by constant 17 to 0x8048484
Special opcode 76: advance Address by 5 to 0x8048489 and Line by 1 to 19
Advance PC by constant 17 to 0x804849a
Special opcode 146: advance Address by 10 to 0x80484a4 and Line by 1 to 20
Special opcode 62: advance Address by 4 to 0x80484a8 and Line by 1 to 21
Special opcode 160: advance Address by 11 to 0x80484b3 and Line by 1 to 22
等等,应该是每条指令的都有了
这里有一个对格式简单的说明 http://hi.baidu.com/piaoling_sky/blog/item/f9654ad21a6ed43d970a169c.html
addr2line 应该也是使用了这几个段的信息的,objdump gdb等也都可以解析这个段的。
使用
strip -d a.out
命令去除掉 这个几个debug 段的话,addr2line 也就无能为力了
你可以自己试一下
可以使用 readelf --sections a.out 看的出来
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubtypes 00000000 .debug_pubtypes
.debug_line 这个段里面就包含了每条汇编指令的地址和对应的源代码行数,源代码名字等信息,
使用readelf -wl a.out 命令就可以查看这个段的内容,比如
readelf -wl a.out
Raw dump of debug contents of section .debug_line:
Offset: 0x0
Length: 277
DWARF Version: 2
Prologue Length: 29
Minimum Instruction Length: 1
Initial value of 'is_stmt': 1
Line Base: -5
Line Range: 14
Opcode Base: 13
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 args
Opcode 3 has 1 args
Opcode 4 has 1 args
Opcode 5 has 1 args
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 args
Opcode 10 has 0 args
Opcode 11 has 0 args
Opcode 12 has 1 args
The Directory Table is empty.
The File Name Table:
Entry Dir Time Size Name
1 0 0 0 main.c //////////////这个是文件名
Line Number Statements:
Extended opcode 2: set Address to 0x8048444
Advance Line by 12 to 13
Copy
Special opcode 90: advance Address by 6 to 0x804844a and Line by 1 to 14
Special opcode 202: advance Address by 14 to 0x8048458 and Line by 1 to 15
Special opcode 174: advance Address by 12 to 0x8048464 and Line by 1 to 16
Special opcode 90: advance Address by 6 to 0x804846a and Line by 1 to 17
Special opcode 132: advance Address by 9 to 0x8048473 and Line by 1 to 18
Advance PC by constant 17 to 0x8048484
Special opcode 76: advance Address by 5 to 0x8048489 and Line by 1 to 19
Advance PC by constant 17 to 0x804849a
Special opcode 146: advance Address by 10 to 0x80484a4 and Line by 1 to 20
Special opcode 62: advance Address by 4 to 0x80484a8 and Line by 1 to 21
Special opcode 160: advance Address by 11 to 0x80484b3 and Line by 1 to 22
等等,应该是每条指令的都有了
这里有一个对格式简单的说明 http://hi.baidu.com/piaoling_sky/blog/item/f9654ad21a6ed43d970a169c.html
addr2line 应该也是使用了这几个段的信息的,objdump gdb等也都可以解析这个段的。
使用
strip -d a.out
命令去除掉 这个几个debug 段的话,addr2line 也就无能为力了
你可以自己试一下
|
有段时间我研究backtrace,还将汇编代码、栈帧这些东西一起研究,有空再研究吧。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。