1.GDB调试基础

1. 不同级别符号表的区别

file cmd

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ g++ main.cpp -o cmd1 -g1
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ g++ main.cpp -o cmd2 -g2
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ g++ main.cpp -o cmd3 -g3
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ g++ main.cpp -o cmd


wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ ll
-rwxrwxrwx 1 wangguangbo wangguangbo  16584 Mar  8 21:25 cmd*
-rwxrwxrwx 1 wangguangbo wangguangbo  16584 Mar  8 21:25 cmd1*
-rwxrwxrwx 1 wangguangbo wangguangbo  32624 Mar  8 21:25 cmd2*
-rwxrwxrwx 1 wangguangbo wangguangbo 115024 Mar  8 21:25 cmd3*

当可执行文件cmd没有调试信息时,空间最小


2. 使用file命令查看文件标识


wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ file cmd 
cmd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=78bdc3e1b12130e4a4dd34030ce4b393e192de1a, for GNU/Linux 3.2.0, not stripped
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ file cmd1
cmd1: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=29da26c551768406ff057c1758b2fbece02599e2, for GNU/Linux 3.2.0, with debug_info, not stripped
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ file cmd2
cmd2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f5bceb7ff34b63351662b48666f5ed236ddbc13a, for GNU/Linux 3.2.0, with debug_info, not stripped
wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ file cmd3
cmd3: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8ac596bd15a4fd6995a2bf0b2822ca4ad01371a3, for GNU/Linux 3.2.0, with debug_info, not stripped

当输出包含debug_info 标识表示当前可执行文件包含调试信息


3. 查看可执行程序的程序段

3.1 cmd的程序段:

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ readelf -S cmd -W
There are 31 section headers, starting at offset 0x3908:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000138 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000510 000510 000151 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          0000000000000662 000662 00001a 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000680 000680 000070 00   A  7   2  8
  [10] .rela.dyn         RELA            00000000000006f0 0006f0 0000f0 18   A  6   0  8
  [11] .rela.plt         RELA            00000000000007e0 0007e0 000060 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 000050 10  AX  0   0 16
  [14] .plt.got          PROGBITS        0000000000001070 001070 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        0000000000001080 001080 000040 10  AX  0   0 16
  [16] .text             PROGBITS        00000000000010c0 0010c0 0001ae 00  AX  0   0 16
  [17] .fini             PROGBITS        0000000000001270 001270 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        0000000000002000 002000 000007 00   A  0   0  4
  [19] .eh_frame_hdr     PROGBITS        0000000000002008 002008 00003c 00   A  0   0  4
  [20] .eh_frame         PROGBITS        0000000000002048 002048 0000cc 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000003d88 002d88 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000003d90 002d90 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000003d98 002d98 000200 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000003f98 002f98 000068 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000004000 003000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000004040 003010 000118 00  WA  0   0 64
  [27] .comment          PROGBITS        0000000000000000 003010 00002b 01  MS  0   0  1
  [28] .symtab           SYMTAB          0000000000000000 003040 000450 18     29  21  8
  [29] .strtab           STRTAB          0000000000000000 003490 00035c 00      0   0  1
  [30] .shstrtab         STRTAB          0000000000000000 0037ec 00011a 00      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),
  D (mbind), l (large), p (processor specific)

3.2 cmd1的程序段:

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ readelf -S cmd1 -W
There are 37 section headers, starting at offset 0x3c90:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000138 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000510 000510 000151 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          0000000000000662 000662 00001a 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000680 000680 000070 00   A  7   2  8
  [10] .rela.dyn         RELA            00000000000006f0 0006f0 0000f0 18   A  6   0  8
  [11] .rela.plt         RELA            00000000000007e0 0007e0 000060 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 000050 10  AX  0   0 16
  [14] .plt.got          PROGBITS        0000000000001070 001070 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        0000000000001080 001080 000040 10  AX  0   0 16
  [16] .text             PROGBITS        00000000000010c0 0010c0 0001ae 00  AX  0   0 16
  [17] .fini             PROGBITS        0000000000001270 001270 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        0000000000002000 002000 000007 00   A  0   0  4
  [19] .eh_frame_hdr     PROGBITS        0000000000002008 002008 00003c 00   A  0   0  4
  [20] .eh_frame         PROGBITS        0000000000002048 002048 0000cc 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000003d88 002d88 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000003d90 002d90 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000003d98 002d98 000200 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000003f98 002f98 000068 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000004000 003000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000004040 003010 000118 00  WA  0   0 64
  [27] .comment          PROGBITS        0000000000000000 003010 00002b 01  MS  0   0  1
  [28] .debug_aranges    PROGBITS        0000000000000000 00303b 000030 00      0   0  1
  [29] .debug_info       PROGBITS        0000000000000000 00306b 000097 00      0   0  1
  [30] .debug_abbrev     PROGBITS        0000000000000000 003102 00007a 00      0   0  1
  [31] .debug_line       PROGBITS        0000000000000000 00317c 00008b 00      0   0  1
  [32] .debug_str        PROGBITS        0000000000000000 003207 00013a 01  MS  0   0  1
  [33] .debug_line_str   PROGBITS        0000000000000000 003341 000031 01  MS  0   0  1
  [34] .symtab           SYMTAB          0000000000000000 003378 000450 18     35  21  8
  [35] .strtab           STRTAB          0000000000000000 0037c8 00035c 00      0   0  1
  [36] .shstrtab         STRTAB          0000000000000000 003b24 00016a 00      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),
  D (mbind), l (large), p (processor specific)

可见使用 -gX 编译选项的可执行文件 .debug 的调试段

3.2 cmd2的程序段

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ readelf -S cmd2 -W
There are 37 section headers, starting at offset 0x7630:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000138 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000510 000510 000151 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          0000000000000662 000662 00001a 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000680 000680 000070 00   A  7   2  8
  [10] .rela.dyn         RELA            00000000000006f0 0006f0 0000f0 18   A  6   0  8
  [11] .rela.plt         RELA            00000000000007e0 0007e0 000060 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 000050 10  AX  0   0 16
  [14] .plt.got          PROGBITS        0000000000001070 001070 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        0000000000001080 001080 000040 10  AX  0   0 16
  [16] .text             PROGBITS        00000000000010c0 0010c0 0001ae 00  AX  0   0 16
  [17] .fini             PROGBITS        0000000000001270 001270 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        0000000000002000 002000 000007 00   A  0   0  4
  [19] .eh_frame_hdr     PROGBITS        0000000000002008 002008 00003c 00   A  0   0  4
  [20] .eh_frame         PROGBITS        0000000000002048 002048 0000cc 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000003d88 002d88 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000003d90 002d90 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000003d98 002d98 000200 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000003f98 002f98 000068 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000004000 003000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000004040 003010 000118 00  WA  0   0 64
  [27] .comment          PROGBITS        0000000000000000 003010 00002b 01  MS  0   0  1
  [28] .debug_aranges    PROGBITS        0000000000000000 00303b 000030 00      0   0  1
  [29] .debug_info       PROGBITS        0000000000000000 00306b 0022d2 00      0   0  1
  [30] .debug_abbrev     PROGBITS        0000000000000000 00533d 000596 00      0   0  1
  [31] .debug_line       PROGBITS        0000000000000000 0058d3 000156 00      0   0  1
  [32] .debug_str        PROGBITS        0000000000000000 005a29 00108d 01  MS  0   0  1
  [33] .debug_line_str   PROGBITS        0000000000000000 006ab6 000262 01  MS  0   0  1
  [34] .symtab           SYMTAB          0000000000000000 006d18 000450 18     35  21  8
  [35] .strtab           STRTAB          0000000000000000 007168 00035c 00      0   0  1
  [36] .shstrtab         STRTAB          0000000000000000 0074c4 00016a 00      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),
  D (mbind), l (large), p (processor specific

比较得出包含的debug段占用空间更大


4.编译选项总结

选项 调试信息详细程度 二进制文件大小 包含的关键信息
-g1 最低级别 最小 基本行号、函数名、变量类型信息
-g2 默认级别(如直接使用-g) 中等 完整行号、函数、变量、结构体布局
-g3 最高级别 最大 额外包含宏定义、内联函数、模板实例化信息

5.使用GDB调试

5.1 不包含符号表的GDB启动信息

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb ./cmd
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./cmd...

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.



(No debugging symbols found in ./cmd)

5.2 包含符号表的GDB启动信息

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb ./cmd1
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...


Reading symbols from ./cmd1...

(gdb) q

**注意 ** : GDB对于符号表的提示不同

局部变量的区别


gdb ./cmd1
(gdb) b main
Breakpoint 1 at 0x11e4: file main.cpp, line 91.
(gdb) r
Starting program: /mnt/d/CMD/cmd1
Breakpoint 1, main () at main.cpp:91
91      int main() {                                                                                                      
(gdb) i locals
No locals.
(gdb) q

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb -q ./cmd2
Reading symbols from ./cmd2...
(gdb) b main
Breakpoint 1 at 0x11e4: file main.cpp, line 91.
(gdb) r
Starting program: /mnt/d/CMD/cmd2                                                                                         

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.cpp:91
91      int main() {                                                                                                      
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /mnt/d/CMD/cmd2                                                                                         
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.cpp:91
91      int main() {                                                                                                      
(gdb) i locals
a = {-8704, 32767, -137661553, 32767, -135812528}
p = 0x6c6f6f705f68652e

区别 : -g2 可以通过 i locals 命令查看到变量信息

5.3 包含符号表的GDB启动信息

-g1 编译选项下的输出

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb -q ./cmd1
Reading symbols from ./cmd1...
(gdb) b main 
Breakpoint 1 at 0x11e4: file main.cpp, line 91.
(gdb) r
Starting program: /mnt/d/CMD/cmd1                                                                                         

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.cpp:91
warning: Source file is more recent than executable.
(gdb) macro expand MAX
expands to: MAX
(gdb) 

-g2 编译选项下的输出

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb -q ./cmd2
Reading symbols from ./cmd2...
(gdb) b main
Breakpoint 1 at 0x11e4: file main.cpp, line 91.
(gdb) r
Starting program: /mnt/d/CMD/cmd2                                                                                        
This GDB supports auto-downloading debuginfo from the following URLs:
 <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.cpp:91
warning: Source file is more recent than executable.
(gdb) i loacals
Undefined info command: "loacals".  Try "help info".
(gdb) i locals
a = {-8704, 32767, -137661553, 32767, -135812528}
p = 0x6c6f6f705f68652e         
(gdb) info macro MAX
Defined at <user-defined>:-1
#define MAX

-g3 编译选项下的输出

wangguangbo@DESKTOP-O5D0MDL:/mnt/d/CMD$ gdb -q ./cmd3
Reading symbols from ./cmd3...
(gdb) b main
Breakpoint 1 at 0x24a4: file main.cpp, line 33.
(gdb) r
Starting program: /mnt/d/CMD/cmd3                                                                                         

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7fffffffdea8) at main.cpp:33
33       int main(int argc, char *argv[]) {                                                                               
(gdb) i locals
a = 0
buf = "\270\336\377\377\377\177\000\000\000+\243-{c\363W \335\377\377\377\177\000\000\300:\240\367\377\177\000\000\377\021
\000\000\000\000\000\000\230\377\377\377\377\377\377\377\270\336\377\377\377\177\000\000\230\303\346\367\377\177\000\000`\
335\377\377\377\177\000\000\022؊\367\377\177\000\000`\335\377\377\377\177\000\000@\303\346\367\377\177\000\000glibcxx.\000 \001\000\000\000\000\000glibcxx..eh_pool"
str = ""
f = {<No data fields>}
(gdb) l
28           printf("cnt: %d\n", cnt);                                                                                    
29           return -2;                                                                                                   
30       }                                                                                                                
31
32
33       int main(int argc, char *argv[]) {                                                                               
34           int a = 123;                                                                                                 
35           char buf[128] = "456";                                                                                       
36           std::string str = "abc";                                                                                     
37
(gdb) macro expand MAX
expands to: (9988)
posted @ 2026-03-23 21:23  BlackSnow  阅读(29)  评论(0)    收藏  举报