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

   轉自:http://blog.csdn.net/huluedeai/article/details/52215532

有時候我們需要知道一個*.so文件或者可執行文件是debug版本的還是release版本的,這時我們有哪些方法呢?

    1.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
沒有輸出

objdumpreadelf功能相似,都可以從二進制文件中讀取相應的信息並顯示,它們的區別在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來判斷是否有調試符號,

    4
但是“ stripped ”只是表示這個可執行文件被 strip 過。沒有“ stripped “說明這個可執行文件沒有被 strip 過,不意味着它編譯時包含了額外的調試信息(-g )
所以這種方法不OK。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章