GDB 调试指南(第 3 章):运行程序与参数传递

← 上一章:断点与观察点 | 目录 | 下一章:单步调试与查看程序状态 →

第 3 章 运行程序与参数传递

很多命令行程序需要带参数运行(比如 ./cmd 123 abc),或者依赖某个环境变量才能正常工作。这一章讲清楚怎么在 GDB 里把这些“启动条件”配置好。

3.1 run [arglist]

run [arglist]   # 运行程序;若指定 arglist,则作为命令行参数传给程序

若省略 arglist,则复用上一次 set args 或上一次 run 留下的参数;都没有设置过时则不带参数启动。

3.2 三种设置参数的方式

方式一:启动 GDB 时直接指定

gdb --args ./my_program arg1 arg2 "arg with space"

方式二:在 GDB 会话中,run 后面直接带参数

(gdb) run arg1 arg2 "arg with space"

方式三:先用 set args 保存参数,再 run(可反复复用)

(gdb) set args arg1 arg2 "arg with space"
(gdb) run        # 使用预设参数运行
(gdb) run        # 再次运行,仍使用相同参数

【新手提示】无论程序重新 run 多少次,只要不手动修改,参数都会被保留——这也是「方式三」比每次手打参数更省事的原因。日常调试同一个程序反复 run 很常见,设一次参数管全程。

查看当前参数:show args

(gdb) show args
Argument list to give program being debugged is "arg1 arg2 \"arg with space\"".

3.3 set args 详解

set args 只是保存参数,不会立即运行程序,需要配合 run 使用。

(gdb) set args arg1 arg2 "arg with space"
(gdb) run

清空参数(不带任何值):

(gdb) set args

清空后再 run,程序将不带任何命令行参数启动,等价于直接执行 ./my_program。

run arglist 与 set args 的关系:

命令 是否立即运行 是否保存供下次复用
run arg1 arg2 是,立即运行 是,会覆盖之前 set args 的设置
set args arg1 arg2 否,仅保存 是

也就是说,run arglist 本质上等价于“先 set args arglist,再 run”。

实战示例:验证带空格的参数

$ gdb -q --args ./cmd 123 abc "1 b 2 d"
(gdb) b 46
(gdb) r
Starting program: /mnt/d/CMD/cmd 123 abc 1\ b\ 2\ d
argv[0]:/mnt/d/CMD/cmd
argv[1]:123
argv[2]:abc
argv[3]:1 b 2 d

Breakpoint 1, main (argc=4, argv=0x7fffffffde58) at main.cpp:46

可以看到含空格的参数 "1 b 2 d" 被 GDB 原样当作一个参数传给了程序(argv[3]),这正是加引号的意义——不加引号会被拆成 4 个独立参数,argc 会变成 6 而不是 4。

3.4 环境变量:set args 管不到的东西

set args 只设置命令行参数(argv),很多程序的行为还依赖环境变量(比如读取 PATH、自定义的配置开关),这部分要用专门的命令:

(gdb) set environment MY_VAR=1        # 设置环境变量
(gdb) show environment MY_VAR          # 查看某个环境变量的值
(gdb) unset environment MY_VAR         # 删除某个环境变量

【新手提示】命令行参数和环境变量是两回事,初学时很容易混淆——“我明明 set args 了为什么程序读不到”,十有八九是把本该用环境变量传的配置,错当成命令行参数在设置。

3.5 需要标准输入/输出重定向怎么办

如果被调试程序需要从文件读输入、或者想把输出单独存一份,set args 的参数列表其实支持类似 Shell 的重定向语法:

(gdb) set args arg1 arg2 < input.txt > output.txt
  • < 重定向标准输入(程序从 input.txt 读数据,而不是等你在终端手动输入)
  • > 重定向标准输出(程序的 printf 等输出写进 output.txt,终端里看不到了)
  • 2> 重定向标准错误

如果程序本来就是交互式程序,需要等用户在终端里实时输入内容,什么都不用设置,直接 run,在 GDB 所在的这个终端窗口里直接输入就行,GDB 不会拦截程序的标准输入。只有明确想从文件读、或者想把输出转存到文件时,才需要上面这行配置。

3.6 【常见误区】run 和 continue 搞混

这是新手几乎必踩的一个坑:

  • run(r):把程序从头开始重新启动一次。如果程序已经在运行中(比如停在某个断点),GDB 会先问你“是否要从头开始”:
    (gdb) r
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    
  • continue(c):从当前暂停的位置接着往下跑,不会重新开始,之前走过的代码、累积的变量状态都还在。

如果你的目的是“从刚才断住的地方继续往下看”,要用 continue;如果不小心按成 run 又确认了重启,之前单步走到的位置、修改过的临时变量全部作废,程序会从 main 重新跑一遍。两个命令效果完全不同,下手前多看一眼。

3.7 小结

  • 命令行参数用 set args / run arglist,环境变量用 set environment,两者互不影响,不要混用。
  • 参数一旦设置会一直保留到你主动修改,适合同一个程序反复调试的场景。
  • 输入输出需要走文件而不是终端交互时,用 set args 自带的 </>/2> 重定向语法。
  • run 是重新开始,continue 是接着跑,这两个命令务必分清楚。

← 上一章:断点与观察点 | 目录 | 下一章:单步调试与查看程序状态 →

posted @ 2026-10-10 08:29  BlackSnow  阅读(9)  评论(0)    收藏  举报