-
调试进程、可执行程序、core文件
gdb调试正在运行的某一进程 $ gdb attach PID $ break xxx $ continue (继续运行)
gdb调试某一可执行程序 $ gdb program $ break xxx $ run (运行程序)
gdb调试需要指定命令行参数的程序 $gdb --args program arg1 arg2 arg3
gdb解析core dump文件 $gdb program core
-
断点
断点基础
break func 设置断点 (函数)
break file:line 设置断点 (文件:行号)
info breakpoints 查看所有断点
delete num 删除断点
enable num 使能断点
disable num 去使能断点
disable 去使能所有断点
enable 使能所有断点
条件断点
break 断点 if 条件
例子:
break 2997 if 0 == strcmp("segrt.xmlui", pcPluginName)
enable XXX
condition num 条件
例子:
(gdb) b 11
Breakpoint 1 at 0x400514: file test1.c, line 11.
(gdb) condition 1 i==5000
command num 为断点设置命令列表
例子:
(gdb)commands num
Type commands for when breakpoint num is hit, one per line.
End with a line saying just "end".
>print pstNode->pcNodeName
>continue
>end
观察断点
watch variable 监控变量 (变量值改变时,断点,并打印变量 新值+旧值;删除时使用delete NUM,用info break查看NUM)
只在特定线程中触发断点
break <location> thread <thread-id>
-
运行
run 运行可执行程序
continue 断点后继续执行
until line 执行到某行
next 单行调试(不进入函数)
step 单步调试(进入函数)
-
变量&内存
print variable 打印变量
print/x variable 以十六进制打印变量
具体如下:
/x 按十六进制格式显示变量
/d 按十进制格式显示变量
/u 按十六进制格式显示无符号整型
/o 按八进制格式显示变量
/t 按二进制格式显示变量
/a 按十六进制格式显示变量
/c 按字符格式显示变量
/f 按浮点数格式显示变量
print *array@len 打印一段连续内存空间中的值。可以查看 数组的一段 、动态分配的数据大小
举例:
int *array = (int *) malloc(len * sizeof(int));
可以使用如下方式查看
print *array@len
display variable 显示变量 (单步调试每一步都会打印此变量;删除时使用delete display NUM)
set variable=value 设置某变量的值
x address 查看地址所指向内存中的值
5. 函数
call func 调用函数
finish 执行完当前函数
return value 从函数返回(返回值value)
-
线程
info threads 查看所有线程
thread num 切换到某一线程
backtrace 查看当前线程的调用栈
frame num 切换到某一栈帧
info locals 查看当前栈帧中的局部变量
thread apply all bt 查看所有线程调用栈
-
信号
info signals / info handle 查看所有信号的处理方式
handle signal keywrod1 keyword2 ... 设置信号处理方式
signal:
具体某一信号 SIGXXX
某一范围内信号 SIGXXX-SIGYYY
所有信号 all
Keyword:
nostop: 信号发生时,GDB不会停住被调试程序运行,但会打印消息告诉你接受到此信号
stop: 信号发生时,GDB停住被调试程序运行
print: 信号发生时,GDB会打印消息告诉你接收到此信号
noprint: 信号发生时,GDB不会打印消息告诉你接收到此信号
pass / noignore: 信号发生时,GDB将此信号交给被调试程序处理
nopass / ignore: 信号发生时,GDB不会将此信号交给被调试程序处理
kill -s signal pid 发送信号signal到pid进程
-
显示
set print pretty 使打印格式更可读
set print elements 300 设置打印长度 (例如:打印字符串时,字符串太长,无法打印全,可以使用此命令设置打印长度)
show print elements 显示打印长度
9. fork后的行为控制
set follow-fork-mode child 调用fork之后,接着调试子进程
set follow-fork-mode parent 调用fork之后,接着调试父进程(默认)
10 . gcc编译生成可供gdb调试的可执行程序
gcc -o test test.c -g 生成调试信息,供GDB等调试器使用
11. 执行系统命令
!command
示例:
(gdb) !ls /home/suph/NVS10-32/
include libs output README.en.md README.md resource source targets tools
(gdb) !pwd
/home/suph/NVS10-32/output
12. set scheduler-locking 命令。这个命令可以控制当程序停止(断点)后,再次运行(继续运行、单步执行)程序时,其他线程是否继续执行。它有几个选项:
set scheduler-locking on
的作用正是:
-
当断点触发、程序暂停时:GDB 会像往常一样停止所有线程,并可能切换到触发断点的线程(具体取决于您的其他设置)。
-
当您下达 continue
, next
, step
等继续运行的命令时:只有当前被选中的线程会恢复执行,所有其他线程将被 GDB 强制挂起,保持暂停状态。
set scheduler-locking off
的详细解释:
当您使用 continue
, next
, step
等命令让程序继续运行时:
-
所有线程都会恢复执行:GDB 不会阻止任何线程的运行。当前线程、其他被暂停的线程都会一起被释放。
-
由操作系统决定谁先运行:线程的执行顺序、哪个线程先得到CPU时间片,完全由操作系统的线程调度器决定。这是一种并发的、不确定的执行状态,最接近程序的真实运行环境。
-
程序暂停时,GDB 可能自动切换线程:当断点触发或程序因信号停止时,GDB 默认会自动切换到触发暂停事件的那个线程,以便您查看上下文。这个行为是 off
模式的一部分。
命令 / 状态 | 继续运行 (c , n , s ) 时的行为 | 适用场景 |
set scheduler-locking off (默认) |
所有线程自由运行,由操作系统调度。 |
观察线程交互、重现竞态条件、调试死锁、常规调试。 |
set scheduler-locking step |
只有单步执行时锁定其他线程;连续运行时所有线程自由运行。 |
最常用、最安全。在精细控制单步时排除干扰,在连续运行时保持真实。 |
set scheduler-locking on |
任何时候继续运行,都只有当前线程运行,其他线程被强制挂起。 |
严格隔离单个线程的执行路径,强制控制执行顺序。风险高,可能引入死锁。 |