目录
一、GDB概述
GDB 是一个开源的调试器,能够让你在程序运行时查看变量的值、单步执行代码、设置断点、查看调用栈等。它支持多种编程语言,包括 C、C++、Fortran、Objective-C 等。GDB 的主要功能包括:
-
设置断点:在指定的代码位置暂停程序执行。
-
单步执行:逐行或逐指令执行代码。
-
查看变量:查看和修改程序中的变量值。
-
查看调用栈:分析程序的执行路径。
-
查看内存:查看和修改内存中的数据。
-
多线程支持:调试多线程程序。
-
反汇编支持:查看程序的汇编代码。
命令简写
| 功能 | 全称 | 简写 |
| 运行程序 | run | r |
| 退出 GDB | quit | q |
| 设置断点 | break | b |
| 继续运行程序(直到遇到下一个断点) | continue | c |
| 逐行执行代码(不进入函数内部) | next | n |
| 逐行执行代码(进入函数内部) | step | s |
| 执行到当前函数的末尾 | finish | fin |
| 查看变量的值 | print | p |
| 查看调用栈 | backtrace | bt |
| 查看所有断点 | info breakpoints | i b |
| 删除断点 | delete breakpoint | d b |
| 禁用断点 | disable breakpoint | dis b |
| 启用断点 | enable breakpoint | en b |
| 查看线程信息 | info threads | i th |
| 切换线程 | thread 2 | th 2 |
| ...... | ...... | ...... |
二、GDB 的基本操作
(一)启动 GDB
在使用 GDB 之前,需要确保程序是用 -g 选项编译的,这样 GDB 才能获取调试信息。
gcc -g -o my_program my_program.c
然后使用以下命令启动 GDB:
gdb ./my_program
启动后,你会看到类似以下的提示:
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 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 "help" for all GDB commands.
(gdb)
(二) 设置断点
断点是调试中的关键工具,它可以让程序在指定的位置暂停执行。在 GDB 中,可以使用 break 命令设置断点:
-
在函数入口设置断点
(gdb) break main -
在文件的指定行设置断点
(gdb) break file.c:10 -
在指定条件满足时设置断点
(gdb) break file.c:10 if x > 10 -
查看所有断点
(gdb) info breakpoints -
删除断点
(gdb) delete breakpoint 1 -
禁用断点
(gdb) disable breakpoint 1 -
启用断点
(gdb) enable breakpoint 1
(三)运行程序
使用 run 命令启动程序:
(gdb) run
如果程序需要输入参数,可以在 run 命令后面直接添加参数
(gdb) run arg1 arg2
(四) 查看变量
在程序暂停时,可以使用 print 命令查看变量的值
(gdb) print variable_name
如果需要查看指针指向的内容,可以使用 * 操作符
(gdb) print *pointer
如果需要查看数组的内容,可以使用以下命令
(gdb) print *array@10
这将打印数组的前 10 个元素。
(五)单步执行
GDB 提供了多种单步执行命令,帮助你逐步跟踪程序的执行过程:
-
逐行执行代码(不进入函数内部)
(gdb) next -
逐行执行代码(进入函数内部)
(gdb) step -
继续运行程序(直到遇到下一个断点)
(gdb) continue -
执行到当前函数的末尾
(gdb) finish -
执行指定的指令
(gdb) nexti -
执行一条汇编指令
(gdb) stepi
(六)查看调用栈
当程序出错时,查看调用栈可以帮助你快速定位问题。使用 backtrace 或 bt 命令查看调用栈
(gdb) backtrace
(七)修改变量
在调试过程中,你还可以修改变量的值,以测试程序在不同情况下的行为
(gdb) set variable_name = new_value
(八)退出 GDB
完成调试后,使用 quit 命令退出 GDB
(gdb) quit
三、GDB 的高级功能
(一)查看内存
GDB 允许你查看和修改内存中的数据。使用 x 命令查看内存内容
(gdb) x/10gx 0x7fffffffe000
-
/10g表示查看 10 个 8 字节的数据。 -
0x7fffffffe000是内存地址。
(二)查看寄存器
使用 info registers 命令查看当前的寄存器状态
(gdb) info registers
(三) 查看线程
如果程序是多线程的,可以使用以下命令查看线程信息
(gdb) info threads
切换到指定线程
(gdb) thread 2
(四)自动显示变量
在调试过程中,某些变量可能需要频繁查看。使用 display 命令可以让 GDB 在每次程序暂停时自动显示变量的值
(gdb) display variable_name
(五)断点管理
GDB 提供了多种断点管理命令:
-
查看所有断点
(gdb) info breakpoints -
删除断点
(gdb) delete breakpoint 1 -
禁用断点
(gdb) disable breakpoint 1 -
启用断点
(gdb) enable breakpoint 1
(六)跟踪变量
如果需要跟踪变量的变化,可以使用 watch 命令设置观察点
(gdb) watch variable_name
当变量的值发生变化时,程序会自动暂停。
(七)反汇编代码
GDB 支持查看程序的汇编代码,使用 disassemble 命令
(gdb) disassemble main
这将显示 main 函数的汇编代码。
(八) 调试核心转储文件
如果程序崩溃并生成了核心转储文件(core dump),可以使用 GDB 加载该文件进行调试
gdb ./my_program core
加载后,可以使用 backtrace 等命令查看崩溃时的调用栈。
(九) 调试远程程序
GDB 支持远程调试,可以通过网络连接到运行在远程机器上的程序。首先,需要在远程机器上启动 GDB 服务器
gdbserver :1234 ./my_program
然后在本地机器上启动 GDB,并连接到远程服务器
gdb ./my_program
(gdb) target remote remote_machine_ip:1234
四、GDB 的实际应用
(一)调试一个简单的 C 程序
假设我们有一个简单的 C 程序 test.c:
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int z = x + y;
printf("The sum is: %d\n", z);
return 0;
}
编译并启动 GDB
gcc -g -o test test.c
gdb ./test
在 GDB 中设置断点并运行程序
(gdb) break main
(gdb) run
程序会在 main 函数入口处暂停。使用 next 命令逐行执行代码,并查看变量的值
(gdb) next
(gdb) print x
(gdb) print y
(gdb) print z
(二)调试多线程程序
假设我们有一个多线程程序 thread_example.c
#include <pthread.h>
#include <stdio.h>
void* thread_function(void* arg) {
int* data = (int*)arg;
printf("Thread: %d\n", *data);
return NULL;
}
int main() {
pthread_t thread1, thread2;
int data1 = 1, data2 = 2;
pthread_create(&thread1, NULL, thread_function, &data1);
pthread_create(&thread2, NULL, thread_function, &data2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
编译并启动 GDB
gcc -g -pthread -o thread_example thread_example.c
gdb ./thread_example
在 GDB 中设置断点并运行程序
(gdb) break thread_function
(gdb) run
程序会在 thread_function 函数入口处暂停。使用 info threads 查看线程信息,并切换到指定线程
(gdb) info threads
(gdb) thread 2
五、GDB 的高级技巧
(一)自定义命令
GDB 允许你定义自己的命令,以简化调试过程。例如,可以定义一个命令来打印某个变量的值
(gdb) define print_x
> print x
> end
然后使用 print_x 命令打印变量 x 的值
(gdb) print_x
(二)调试优化代码
在调试优化后的代码时,GDB 的行为可能会有所不同。优化可能会导致某些变量被优化掉,或者代码的执行顺序发生变化。为了调试优化后的代码,可以使用以下命令
(gdb) set follow-fork-mode child
这将让 GDB 跟踪子进程。
(三) 调试信号
GDB 允许你捕获和处理信号。例如,可以捕获 SIGSEGV 信号并查看调用栈
(gdb) handle SIGSEGV stop print
(gdb) run
当程序收到 SIGSEGV 信号时,GDB 会暂停程序并打印调用栈。
(四)调试共享库
如果程序使用了共享库,GDB 可以加载和调试这些库。使用以下命令加载共享库
(gdb) sharedlibrary
这将显示所有加载的共享库。
(五) 调试 Python 程序
GDB 也支持调试 Python 程序。可以使用 py-bt 命令查看 Python 的调用栈
(gdb) py-bt
六、总结
GDB 是一个功能强大的调试工具,它可以帮助开发者快速定位和解决程序中的问题。通过本文的介绍,你已经掌握了 GDB 的基本操作和高级功能。在实际开发中,熟练使用 GDB 将大大提高你的调试效率。
1542

被折叠的 条评论
为什么被折叠?



