红联Linux门户
Linux帮助

Linux下查看*.so和可执行程序是Debug版本方法

发布时间:2016-08-16 15:02:59来源:linux网站作者:忽略的爱
有时候我们需要知道一个*.so文件或者可执行文件是debug版本的还是release版本的,这时我们有哪些方法呢?
 
readelf -S filename |grep debug
比如:
g++ thread.cpp -o thread_test_nodebug -lpthread
readelf -S thread_test_nodebug
yanyang@ubuntu:~/MyGit/thread$ readelf -S thread_test_nodebug
There are 30 section headers, starting at offset 0x11e0:
Section Headers:
[Nr] Name              Type             Address           Offset
Size              EntSize          Flags  Link  Info  Align
[ 0]                   NULL             0000000000000000  00000000
0000000000000000  0000000000000000           0     0     0
[ 1] .interp           PROGBITS         0000000000400238  00000238
000000000000001c  0000000000000000   A       0     0     1
[ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
0000000000000020  0000000000000000   A       0     0     4
[ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
0000000000000024  0000000000000000   A       0     0     4
[ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
0000000000000030  0000000000000000   A       5     0     8
[ 5] .dynsym           DYNSYM           00000000004002c8  000002c8
0000000000000198  0000000000000018   A       6     1     8
[ 6] .dynstr           STRTAB           0000000000400460  00000460
00000000000001a8  0000000000000000   A       0     0     1
[ 7] .gnu.version      VERSYM           0000000000400608  00000608
0000000000000022  0000000000000002   A       5     0     2
[ 8] .gnu.version_r    VERNEED          0000000000400630  00000630
0000000000000060  0000000000000000   A       6     3     8
[ 9] .rela.dyn         RELA             0000000000400690  00000690
0000000000000030  0000000000000018   A       5     0     8
[10] .rela.plt         RELA             00000000004006c0  000006c0
0000000000000120  0000000000000018   A       5    12     8
[11] .init             PROGBITS         00000000004007e0  000007e0
000000000000001a  0000000000000000  AX       0     0     4
[12] .plt              PROGBITS         0000000000400800  00000800
00000000000000d0  0000000000000010  AX       0     0     16
[13] .text             PROGBITS         00000000004008d0  000008d0
00000000000002f2  0000000000000000  AX       0     0     16
[14] .fini             PROGBITS         0000000000400bc4  00000bc4
0000000000000009  0000000000000000  AX       0     0     4
[15] .rodata           PROGBITS         0000000000400bd0  00000bd0
0000000000000054  0000000000000000   A       0     0     8
[16] .eh_frame_hdr     PROGBITS         0000000000400c24  00000c24
000000000000004c  0000000000000000   A       0     0     4
[17] .eh_frame         PROGBITS         0000000000400c70  00000c70
000000000000015c  0000000000000000   A       0     0     8
[18] .init_array       INIT_ARRAY       0000000000600de8  00000de8
0000000000000010  0000000000000000  WA       0     0     8
[19] .fini_array       FINI_ARRAY       0000000000600df8  00000df8
0000000000000008  0000000000000000  WA       0     0     8
[20] .jcr              PROGBITS         0000000000600e00  00000e00
0000000000000008  0000000000000000  WA       0     0     8
[21] .dynamic          DYNAMIC          0000000000600e08  00000e08
00000000000001f0  0000000000000010  WA       6     0     8
[22] .got              PROGBITS         0000000000600ff8  00000ff8
0000000000000008  0000000000000008  WA       0     0     8
[23] .got.plt          PROGBITS         0000000000601000  00001000
0000000000000078  0000000000000008  WA       0     0     8
[24] .data             PROGBITS         0000000000601078  00001078
0000000000000010  0000000000000000  WA       0     0     8
[25] .bss              NOBITS           00000000006010a0  00001088
0000000000000118  0000000000000000  WA       0     0     32
[26] .comment          PROGBITS         0000000000000000  00001088
000000000000004d  0000000000000001  MS       0     0     1
[27] .shstrtab         STRTAB           0000000000000000  000010d5
0000000000000108  0000000000000000           0     0     1
[28] .symtab           SYMTAB           0000000000000000  00001960
0000000000000768  0000000000000018          29    48     8
[29] .strtab           STRTAB           0000000000000000  000020c8
000000000000041e  0000000000000000           0     0     1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
yanyang@ubuntu:~/MyGit/thread$ g++ -g thread.cpp -o thread_test_debug -lpthread
yanyang@ubuntu:~/MyGit/thread$ readelf -S thread_test_debug
There are 35 section headers, starting at offset 0x3b20:
Section Headers:
[Nr] Name              Type             Address           Offset
Size              EntSize          Flags  Link  Info  Align
[ 0]                   NULL             0000000000000000  00000000
0000000000000000  0000000000000000           0     0     0
[ 1] .interp           PROGBITS         0000000000400238  00000238
000000000000001c  0000000000000000   A       0     0     1
[ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
0000000000000020  0000000000000000   A       0     0     4
[ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
0000000000000024  0000000000000000   A       0     0     4
[ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
0000000000000030  0000000000000000   A       5     0     8
[ 5] .dynsym           DYNSYM           00000000004002c8  000002c8
0000000000000198  0000000000000018   A       6     1     8
[ 6] .dynstr           STRTAB           0000000000400460  00000460
00000000000001a8  0000000000000000   A       0     0     1
[ 7] .gnu.version      VERSYM           0000000000400608  00000608
0000000000000022  0000000000000002   A       5     0     2
[ 8] .gnu.version_r    VERNEED          0000000000400630  00000630
0000000000000060  0000000000000000   A       6     3     8
[ 9] .rela.dyn         RELA             0000000000400690  00000690
0000000000000030  0000000000000018   A       5     0     8
[10] .rela.plt         RELA             00000000004006c0  000006c0
0000000000000120  0000000000000018   A       5    12     8
[11] .init             PROGBITS         00000000004007e0  000007e0
000000000000001a  0000000000000000  AX       0     0     4
[12] .plt              PROGBITS         0000000000400800  00000800
00000000000000d0  0000000000000010  AX       0     0     16
[13] .text             PROGBITS         00000000004008d0  000008d0
00000000000002f2  0000000000000000  AX       0     0     16
[14] .fini             PROGBITS         0000000000400bc4  00000bc4
0000000000000009  0000000000000000  AX       0     0     4
[15] .rodata           PROGBITS         0000000000400bd0  00000bd0
0000000000000054  0000000000000000   A       0     0     8
[16] .eh_frame_hdr     PROGBITS         0000000000400c24  00000c24
000000000000004c  0000000000000000   A       0     0     4
[17] .eh_frame         PROGBITS         0000000000400c70  00000c70
000000000000015c  0000000000000000   A       0     0     8
[18] .init_array       INIT_ARRAY       0000000000600de8  00000de8
0000000000000010  0000000000000000  WA       0     0     8
[19] .fini_array       FINI_ARRAY       0000000000600df8  00000df8
0000000000000008  0000000000000000  WA       0     0     8
[20] .jcr              PROGBITS         0000000000600e00  00000e00
0000000000000008  0000000000000000  WA       0     0     8
[21] .dynamic          DYNAMIC          0000000000600e08  00000e08
00000000000001f0  0000000000000010  WA       6     0     8
[22] .got              PROGBITS         0000000000600ff8  00000ff8
0000000000000008  0000000000000008  WA       0     0     8
[23] .got.plt          PROGBITS         0000000000601000  00001000
0000000000000078  0000000000000008  WA       0     0     8
[24] .data             PROGBITS         0000000000601078  00001078
0000000000000010  0000000000000000  WA       0     0     8
[25] .bss              NOBITS           00000000006010a0  00001088
0000000000000118  0000000000000000  WA       0     0     32
[26] .comment          PROGBITS         0000000000000000  00001088
000000000000004d  0000000000000001  MS       0     0     1
[27] .debug_aranges    PROGBITS         0000000000000000  000010d5
0000000000000030  0000000000000000           0     0     1
[28] .debug_info       PROGBITS         0000000000000000  00001105
0000000000001608  0000000000000000           0     0     1
[29] .debug_abbrev     PROGBITS         0000000000000000  0000270d
00000000000003ef  0000000000000000           0     0     1
[30] .debug_line       PROGBITS         0000000000000000  00002afc
0000000000000269  0000000000000000           0     0     1
[31] .debug_str        PROGBITS         0000000000000000  00002d65
0000000000000c72  0000000000000001  MS       0     0     1
[32] .shstrtab         STRTAB           0000000000000000  000039d7
0000000000000148  0000000000000000           0     0     1
[33] .symtab           SYMTAB           0000000000000000  000043e0
00000000000007e0  0000000000000018          34    53     8
[34] .strtab           STRTAB           0000000000000000  00004bc0
000000000000041e  0000000000000000           0     0     1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
 
当然还有另外一种方法来判断就是
yanyang@ubuntu:~/MyGit/thread$ objdump -g thread_test_debug |grep debug
thread_test_debug:     file format elf64-x86-64
Contents of the .debug_aranges section:
Offset into .debug_info:  0x0
Contents of the .debug_info section:
<2f1>   DW_AT_name        : (indirect string, offset: 0xa07): __debug
<11ca>   DW_AT_name        : (indirect string, offset: 0x521): __gnu_debug
Contents of the .debug_abbrev section:
Raw dump of debug contents of section .debug_line:
7     /usr/include/c++/4.8/debug
17    7       0       0       debug.h
Contents of the .debug_str section:
0x00000520 005f5f67 6e755f64 65627567 00766677 .__gnu_debug.vfw
0x00000a00 725f7479 7065005f 5f646562 75670074 r_type.__debug.t
yanyang@ubuntu:~/MyGit/thread$ objdump -g thread_test_nodebug |grep debug
thread_test_nodebug:     file format elf64-x86-64
 
但是有人说objdump -g 出来的结果也不一定正确,这个有待确定,也是一种尝试的方法吧。
看网上还有人用:readelf --debug-dump=line 
yanyang@ubuntu:~/MyGit/thread$ readelf --debug-dump=line thread_test_debug
Raw dump of debug contents of section .debug_line:
Offset:                      0x0
Length:                      613
DWARF Version:               2
Prologue Length:             525
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 (offset 0x1b):
1     /usr/include/c++/4.8
2     /usr/include
3     /usr/lib/gcc/x86_64-linux-gnu/4.8/include
4     /usr/include/c++/4.8/bits
5     /usr/include/x86_64-linux-gnu/c++/4.8/bits
6     /usr/include/c++/4.8/ext
7     /usr/include/c++/4.8/debug
8     /usr/include/x86_64-linux-gnu/bits
The File Name Table (offset 0x104):
Entry Dir     Time    Size    Name
1     0       0       0       thread.cpp
2     1       0       0       iostream
3     0       0       0       <built-in>
4     2       0       0       stdio.h
5     3       0       0       stddef.h
6     2       0       0       wchar.h
7     1       0       0       cwchar
8     4       0       0       char_traits.h
9     5       0       0       c++config.h
10    1       0       0       clocale
11    4       0       0       ios_base.h
12    1       0       0       cwctype
13    1       0       0       iosfwd
14    2       0       0       time.h
15    6       0       0       new_allocator.h
16    6       0       0       numeric_traits.h
17    7       0       0       debug.h
18    2       0       0       locale.h
19    8       0       0       types.h
20    5       0       0       atomic_word.h
21    2       0       0       wctype.h
Line Number Statements:
[0x00000217]  Extended opcode 2: set Address to 0x4009bd
[0x00000222]  Advance Line by 9 to 10
[0x00000224]  Copy
[0x00000225]  Special opcode 174: advance Address by 12 to 0x4009c9 and Line by 1 to 11
[0x00000226]  Special opcode 132: advance Address by 9 to 0x4009d2 and Line by 1 to 12
[0x00000227]  Advance PC by 41 to 0x4009fb
[0x00000229]  Special opcode 6: advance Address by 0 to 0x4009fb and Line by 1 to 13
[0x0000022a]  Special opcode 36: advance Address by 2 to 0x4009fd and Line by 3 to 16
[0x0000022b]  Special opcode 134: advance Address by 9 to 0x400a06 and Line by 3 to 19
[0x0000022c]  Special opcode 175: advance Address by 12 to 0x400a12 and Line by 2 to 21
[0x0000022d]  Special opcode 174: advance Address by 12 to 0x400a1e and Line by 1 to 22
[0x0000022e]  Advance PC by 58 to 0x400a58
[0x00000230]  Special opcode 6: advance Address by 0 to 0x400a58 and Line by 1 to 23
[0x00000231]  Advance PC by 49 to 0x400a89
[0x00000233]  Special opcode 7: advance Address by 0 to 0x400a89 and Line by 2 to 25
[0x00000234]  Special opcode 91: advance Address by 6 to 0x400a8f and Line by 2 to 27
[0x00000235]  Advance Line by -8 to 19
[0x00000237]  Advance PC by 41 to 0x400ab8
[0x00000239]  Copy
[0x0000023a]  Extended opcode 4: set Discriminator to 1
[0x0000023e]  Set is_stmt to 0
[0x0000023f]  Special opcode 61: advance Address by 4 to 0x400abc and Line by 0 to 19
[0x00000240]  Set is_stmt to 1
[0x00000241]  Advance Line by 12 to 31
[0x00000243]  Special opcode 145: advance Address by 10 to 0x400ac6 and Line by 0 to 31
[0x00000244]  Special opcode 132: advance Address by 9 to 0x400acf and Line by 1 to 32
[0x00000245]  Advance PC by constant 17 to 0x400ae0
[0x00000246]  Special opcode 88: advance Address by 6 to 0x400ae6 and Line by -1 to 31
[0x00000247]  Extended opcode 4: set Discriminator to 1
[0x0000024b]  Set is_stmt to 0
[0x0000024c]  Special opcode 61: advance Address by 4 to 0x400aea and Line by 0 to 31
[0x0000024d]  Set is_stmt to 1
[0x0000024e]  Special opcode 92: advance Address by 6 to 0x400af0 and Line by 3 to 34
[0x0000024f]  Special opcode 173: advance Address by 12 to 0x400afc and Line by 0 to 34
[0x00000250]  Special opcode 201: advance Address by 14 to 0x400b0a and Line by 0 to 34
[0x00000251]  Extended opcode 4: set Discriminator to 1
[0x00000255]  Set is_stmt to 0
[0x00000256]  Special opcode 89: advance Address by 6 to 0x400b10 and Line by 0 to 34
[0x00000257]  Set File Name to entry 2 in the File Name Table
[0x00000259]  Set is_stmt to 1
[0x0000025a]  Advance Line by 40 to 74
[0x0000025c]  Special opcode 131: advance Address by 9 to 0x400b19 and Line by 0 to 74
[0x0000025d]  Set File Name to entry 1 in the File Name Table
[0x0000025f]  Advance Line by -40 to 34
[0x00000261]  Advance PC by constant 17 to 0x400b2a
[0x00000262]  Special opcode 187: advance Address by 13 to 0x400b37 and Line by 0 to 34
[0x00000263]  Special opcode 33: advance Address by 2 to 0x400b39 and Line by 0 to 34
[0x00000264]  Special opcode 61: advance Address by 4 to 0x400b3d and Line by 0 to 34
[0x00000265]  Advance PC by constant 17 to 0x400b4e
[0x00000266]  Extended opcode 1: End of Sequence
yanyang@ubuntu:~/MyGit/thread$ readelf --debug-dump=line thread_test_nodebug
没有输出
 
objdump和readelf功能相似,都可以从二进制文件中读取相应的信息并显示,它们的区别在readelf.c中有相关的说明:
/* The difference between readelf and objdump:
Both programs are capable of displaying the contents of ELF format files,
so why does the binutils project have two file dumpers ?
The reason is that objdump sees an ELF file through a BFD filter of the
world; if BFD has a bug where, say, it disagrees about a machine constant
in e_flags, then the odds are good that it will remain internally
consistent.  The linker sees it the BFD way, objdump sees it the BFD way,
GAS sees it the BFD way.  There was need for a tool to go find out what
the file actually says.
This is why the readelf program does not link against the BFD library - it
exists as an independent program to help verify the correct working of BFD.
There is also the case that readelf can provide more information about an
ELF file than is provided by objdump.  In particular it can display DWARF
debugging information which (at the moment) objdump cannot.  */
 
第一个区别,objdump使用了bfd库进行文件读取,而readelf则没有,另外写的一套代码,且对一些条件的判断并不是很严格。比如对于没有指定处理方式的CPU类型,BFD库将拒绝往下执行,readelf还是可以显示其内容。
第二个区别,readelf可以显示调试信息,而objdump则没有。但是实际上bfd库支持DWARF的处理,通过简单处理objdump也可以显示调试信息,就如同nm做的那样。
有人说用file命令看有没有stripped来判断是否有调试符号,
 
但是“ stripped ”只是表示这个可执行文件被 strip 过。没有“ stripped “说明这个可执行文件没有被 strip 过,不意味着它编译时包含了额外的调试信息(-g )
所以这种方法不OK。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/23364.html