3. 启动与退出:启动GDB、设置运行参数、退出GDB、常用启动选项
调试多文件项目,第一步就是要把GDB请出来。这事儿看着简单,但我在带团队时发现,很多新手连启动都搞不利索。说白了,启动方式选对了,后面能省一半力气。今天咱们就把启动与退出这点事儿聊透。
3.1 启动GDB的几种姿势
我个人习惯把启动方式分成三类,你根据场景选就行。
3.1.1 直接启动,再加载程序
最基础的方式。先让GDB跑起来,再告诉它要调试谁。
$ gdb
(gdb) file ./my_project
(gdb) break main
(gdb) run
嗯,这里要注意:file命令加载的是可执行文件,不是源码。我见过有人拿file去加载.c文件,结果GDB一脸懵。
3.1.2 启动时直接指定程序
这是我最常用的方式,省一步是一步。
$ gdb ./my_project
启动后GDB会自动加载符号表。如果你有core dump文件,也可以一并带上:
$ gdb ./my_project core.12345
我在项目中遇到过一回,程序崩溃后core文件死活打不开。后来发现是ulimit -c unlimited没设。你想想看,折腾半天结果是个配置问题,多冤。
3.1.3 附加到正在运行的进程
有时候程序已经跑起来了,你不能停。比如服务器程序,停了就影响线上业务。这时候用attach:
$ gdb -p 12345
# 或者
$ gdb
(gdb) attach 12345
12345是进程PID。我曾经用这招调试过一个内存泄漏的守护进程,不用重启,直接挂上去看堆栈,爽得很。
detach释放,别把人家进程一直挂着。
3.2 设置运行参数
多文件项目经常需要传参数。比如你的程序要读一个配置文件:
$ ./my_project --config /etc/app.conf --verbose
在GDB里怎么传?三种方法。
3.2.1 启动时直接传参
$ gdb --args ./my_project --config /etc/app.conf --verbose
--args后面的所有内容都会原样传给程序。我个人觉得这是最清晰的方式,一眼就能看到全部参数。
3.2.2 进入GDB后用set args
$ gdb ./my_project
(gdb) set args --config /etc/app.conf --verbose
(gdb) run
如果你要清空参数,用set args不加任何内容就行。
3.2.3 设置环境变量
有些项目依赖环境变量,比如LD_PRELOAD或者PATH。在GDB里这样搞:
(gdb) set environment LD_LIBRARY_PATH /usr/local/lib
(gdb) show environment
我曾经调试一个动态库加载失败的问题,查了半天发现是LD_LIBRARY_PATH没传进去。从那以后,我每次调试前都会用show environment确认一遍环境变量。
.gdbinit文件里。这样每次启动GDB,参数自动就位。
3.3 退出GDB
退出这事儿,说简单也简单,说复杂也有坑。
3.3.1 正常退出
(gdb) quit
# 或者简写
(gdb) q
如果程序还在运行,GDB会问你要不要终止它。输入y确认就行。
3.3.2 强制退出
有时候GDB卡住了,比如网络连接断了或者目标板没响应。这时候:
按 Ctrl + D
# 或者
按 Ctrl + C 然后 quit
嗯,这里要注意:Ctrl + C在GDB里是中断程序执行,不是退出GDB。我见过有人狂按Ctrl + C想退出,结果程序被中断了无数次,GDB还坚挺着。
detach释放附加的进程,否则目标进程会被杀掉。
3.4 常用启动选项
GDB的启动选项很多,但常用的就这几个。我整理了一张表,你收藏一下。
| 选项 | 作用 | 我什么时候用 |
|---|---|---|
-q |
静默启动,不显示版本信息 | 每次都用,省得看那一大段版权声明 |
-tui |
启动文本界面模式 | 调试多文件时,可以同时看源码和命令 |
-x |
执行GDB脚本文件 | 批量设置断点、打印变量,省得手动敲 |
-ex |
启动后执行一条命令 | 比如 gdb -ex "break main" -ex "run" ./a.out |
-batch |
批处理模式,执行完命令就退出 | 自动化测试脚本里用,不交互 |
-cd |
指定工作目录 | 项目源码不在当前目录时用 |
举个例子,我经常这样启动:
$ gdb -q -tui -ex "set args -v" ./my_project
这一行干了三件事:静默启动、打开TUI界面、设置运行参数。省事吧?
-ex里写了个run,结果程序直接跑起来了,我还没来得及设断点。后来学乖了,先用-ex "break main",再用-ex "run"。顺序很重要。
3.5 知识体系一览
说了这么多,咱们用一张图把启动与退出的核心逻辑串起来。你一看就明白。
这张图把咱们今天聊的内容全串起来了。启动方式、参数设置、退出方式、启动选项,四个维度,清清楚楚。你调试的时候,按图索骥就行。
好了,启动与退出就聊到这儿。记住一句话:启动选对姿势,退出留好后路。下次咱们接着聊断点设置,那才是调试的重头戏。
gdb ./a.out,参数传递、环境变量、启动选项,每个细节都可能影响你的调试效率。多花一分钟配置,省下半小时排查。
可可精品资料库