软件开发过程中,调试是必不可少的环节之一,让可执行文件”明牌“执行,不会漏过每一行代码,每一个变量的信息。从而帮助开发者快速定位到问题点。
- 先看下没有调试信息的可执行文件是什么样子?
 
root@localhost:~/testWorkSpace/CPP11/vector$ readelf -S ./build/move 
There are 30 section headers, starting at offset 0x32e0:Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .interp           PROGBITS         0000000000000238  00000238000000000000001c  0000000000000000   A       0     0     1[ 2] .note.ABI-tag     NOTE             0000000000000254  000002540000000000000020  0000000000000000   A       0     0     4[ 3] .note.gnu.build-i NOTE             0000000000000274  000002740000000000000024  0000000000000000   A       0     0     4[ 4] .gnu.hash         GNU_HASH         0000000000000298  000002980000000000000024  0000000000000000   A       5     0     8[ 5] .dynsym           DYNSYM           00000000000002c0  000002c00000000000000198  0000000000000018   A       6     1     8[ 6] .dynstr           STRTAB           0000000000000458  00000458000000000000019c  0000000000000000   A       0     0     1[ 7] .gnu.version      VERSYM           00000000000005f4  000005f40000000000000022  0000000000000002   A       5     0     2[ 8] .gnu.version_r    VERNEED          0000000000000618  000006180000000000000080  0000000000000000   A       6     3     8[ 9] .rela.dyn         RELA             0000000000000698  000006980000000000000138  0000000000000018   A       5     0     8[10] .rela.plt         RELA             00000000000007d0  000007d000000000000000a8  0000000000000018  AI       5    23     8[11] .init             PROGBITS         0000000000000878  000008780000000000000017  0000000000000000  AX       0     0     4[12] .plt              PROGBITS         0000000000000890  000008900000000000000080  0000000000000010  AX       0     0     16[13] .plt.got          PROGBITS         0000000000000910  000009100000000000000008  0000000000000008  AX       0     0     8[14] .text             PROGBITS         0000000000000920  000009200000000000000512  0000000000000000  AX       0     0     16[15] .fini             PROGBITS         0000000000000e34  00000e340000000000000009  0000000000000000  AX       0     0     4[16] .rodata           PROGBITS         0000000000000e40  00000e400000000000000005  0000000000000000   A       0     0     4[17] .eh_frame_hdr     PROGBITS         0000000000000e48  00000e4800000000000000dc  0000000000000000   A       0     0     4[18] .eh_frame         PROGBITS         0000000000000f28  00000f2800000000000003c0  0000000000000000   A       0     0     8[19] .gcc_except_table PROGBITS         00000000000012e8  000012e80000000000000019  0000000000000000   A       0     0     1[20] .init_array       INIT_ARRAY       0000000000201d50  00001d500000000000000010  0000000000000008  WA       0     0     8[21] .fini_array       FINI_ARRAY       0000000000201d60  00001d600000000000000008  0000000000000008  WA       0     0     8[22] .dynamic          DYNAMIC          0000000000201d68  00001d680000000000000210  0000000000000010  WA       6     0     8[23] .got              PROGBITS         0000000000201f78  00001f780000000000000088  0000000000000008  WA       0     0     8[24] .data             PROGBITS         0000000000202000  000020000000000000000018  0000000000000000  WA       0     0     8[25] .bss              NOBITS           0000000000202020  000020180000000000000118  0000000000000000  WA       0     0     32[26] .comment          PROGBITS         0000000000000000  000020180000000000000029  0000000000000001  MS       0     0     1[27] .symtab           SYMTAB           0000000000000000  000020480000000000000a08  0000000000000018          28    48     8[28] .strtab           STRTAB           0000000000000000  00002a50000000000000077e  0000000000000000           0     0     1[29] .shstrtab         STRTAB           0000000000000000  000031ce0000000000000110  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),l (large), p (processor specific)
 
使用gdb工具调试运行上述文件,只能看到一行行指令,是没有代码的。
- 再看下带有调试信息的可执行文件
 
root@localhost:~/testWorkSpace/CPP11/vector$ readelf -S ./build/move 
There are 36 section headers, starting at offset 0xb8c8:Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .interp           PROGBITS         0000000000000238  00000238000000000000001c  0000000000000000   A       0     0     1[ 2] .note.ABI-tag     NOTE             0000000000000254  000002540000000000000020  0000000000000000   A       0     0     4[ 3] .note.gnu.build-i NOTE             0000000000000274  000002740000000000000024  0000000000000000   A       0     0     4[ 4] .gnu.hash         GNU_HASH         0000000000000298  000002980000000000000024  0000000000000000   A       5     0     8[ 5] .dynsym           DYNSYM           00000000000002c0  000002c00000000000000198  0000000000000018   A       6     1     8[ 6] .dynstr           STRTAB           0000000000000458  00000458000000000000019c  0000000000000000   A       0     0     1[ 7] .gnu.version      VERSYM           00000000000005f4  000005f40000000000000022  0000000000000002   A       5     0     2[ 8] .gnu.version_r    VERNEED          0000000000000618  000006180000000000000080  0000000000000000   A       6     3     8[ 9] .rela.dyn         RELA             0000000000000698  000006980000000000000138  0000000000000018   A       5     0     8[10] .rela.plt         RELA             00000000000007d0  000007d000000000000000a8  0000000000000018  AI       5    23     8[11] .init             PROGBITS         0000000000000878  000008780000000000000017  0000000000000000  AX       0     0     4[12] .plt              PROGBITS         0000000000000890  000008900000000000000080  0000000000000010  AX       0     0     16[13] .plt.got          PROGBITS         0000000000000910  000009100000000000000008  0000000000000008  AX       0     0     8[14] .text             PROGBITS         0000000000000920  000009200000000000000512  0000000000000000  AX       0     0     16[15] .fini             PROGBITS         0000000000000e34  00000e340000000000000009  0000000000000000  AX       0     0     4[16] .rodata           PROGBITS         0000000000000e40  00000e400000000000000005  0000000000000000   A       0     0     4[17] .eh_frame_hdr     PROGBITS         0000000000000e48  00000e4800000000000000dc  0000000000000000   A       0     0     4[18] .eh_frame         PROGBITS         0000000000000f28  00000f2800000000000003c0  0000000000000000   A       0     0     8[19] .gcc_except_table PROGBITS         00000000000012e8  000012e80000000000000019  0000000000000000   A       0     0     1[20] .init_array       INIT_ARRAY       0000000000201d50  00001d500000000000000010  0000000000000008  WA       0     0     8[21] .fini_array       FINI_ARRAY       0000000000201d60  00001d600000000000000008  0000000000000008  WA       0     0     8[22] .dynamic          DYNAMIC          0000000000201d68  00001d680000000000000210  0000000000000010  WA       6     0     8[23] .got              PROGBITS         0000000000201f78  00001f780000000000000088  0000000000000008  WA       0     0     8[24] .data             PROGBITS         0000000000202000  000020000000000000000018  0000000000000000  WA       0     0     8[25] .bss              NOBITS           0000000000202020  000020180000000000000118  0000000000000000  WA       0     0     32[26] .comment          PROGBITS         0000000000000000  000020180000000000000029  0000000000000001  MS       0     0     1[27] .debug_aranges    PROGBITS         0000000000000000  000020410000000000000150  0000000000000000           0     0     1[28] .debug_info       PROGBITS         0000000000000000  000021910000000000003fe5  0000000000000000           0     0     1[29] .debug_abbrev     PROGBITS         0000000000000000  000061760000000000000755  0000000000000000           0     0     1[30] .debug_line       PROGBITS         0000000000000000  000068cb0000000000000623  0000000000000000           0     0     1[31] .debug_str        PROGBITS         0000000000000000  00006eee000000000000351d  0000000000000001  MS       0     0     1[32] .debug_ranges     PROGBITS         0000000000000000  0000a40b0000000000000140  0000000000000000           0     0     1[33] .symtab           SYMTAB           0000000000000000  0000a5500000000000000a98  0000000000000018          34    54     8[34] .strtab           STRTAB           0000000000000000  0000afe8000000000000077e  0000000000000000           0     0     1[35] .shstrtab         STRTAB           0000000000000000  0000b766000000000000015e  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),l (large), p (processor specific)
 
好像没啥区别,过滤下看看
root@localhost:~/testWorkSpace/CPP11/vector$ readelf -S ./build/move | grep debug[27] .debug_aranges    PROGBITS         0000000000000000  00002041[28] .debug_info       PROGBITS         0000000000000000  00002191[29] .debug_abbrev     PROGBITS         0000000000000000  00006176[30] .debug_line       PROGBITS         0000000000000000  000068cb[31] .debug_str        PROGBITS         0000000000000000  00006eee[32] .debug_ranges     PROGBITS         0000000000000000  0000a40b
 
可执行文件中,正是多加了这些字段信息,才让GDB工具可以“明牌”运行。
- 看到了目标效果,绕回本文主题,CMake工具如何生成带有调试信息的执行文件呢?
 
在CMake.txt文件中,设置如下编译参数就可以了(适用于CMake 3.14.7 版本)
add_definitions("-Wall -g")
set(CMAKE_BUILD_TYPE "Debug")