GDB Notebook

利用 GDB 可以做四种主要的事情来帮助调试:

  • 启动程序,指定参数
  • 使程序在指定条件下停止
  • 检查程序停止时发生了什么
  • 更改程序中的内容

截至目前,GDB 15.1 支持的语言包括 Ada, Assembly, C, C++, D, Fortran, Go, Objective-C, OpenCL, Modula-2, Pascal ,Rust.

下面将介绍 GDB 调试的主要用法。

启动程序

编译文件时需要带上调试信息,对于 C++ 需要编译时带上 -g 参数,对于 Rust 需要编译

对于已经编译好的二进制文件,可以通过 readelf -S <program> | grep debug 检查是否带有调试段

调试未运行程序

通过 gdb <program> 来加载编译好的二进制文件,在 gdb 中 可以通过 run 或者 run <args> 进行运行,并选择是否携带参数。

此外还可以通过先 set args <args> 的方式,先设定参数,然后再 run 来运行

调试运行中程序

使用 ps -ef | grep <proc_name> 获得 pid,然后进入 gdb 后通过 attach <pid> 的方式进行调试

如果运行的程序没有调试信息,可以通过 file <program> 的形式加载symbols

断点

增加断点

在 gdb 中断点命令为 break,可以通过以下方式增加断点:

  • 根据行号: b <filename>:<lineno> 注意这里文件名可以不需要写完整路径,gdb 可以自己推断
  • 根据函数名:b <funcname>
  • 根据条件: b <filename>:<lineno> if x==0

此外还有特殊断点:

  • 正则断点:rbreak <filename>:<regex> 可以通过正则的方式设置断点,例如 rbreak <filename>:^print 设置以 print 开头的函数
  • 临时断点:tbreak,只使用一次

操作断点

禁用或启用

disable      #禁用所有断点
disable bnum #禁用标号为bnum的断点
enable       #启用所有断点
enable bnum  #启用标号为bnum的断点

清除断点

clear           #删除当前行所有breakpoints
clear function  #删除函数名为function处的断点
clear filename:function #删除文件filename中函数function处的断点
clear lineNum           #删除行号为lineNum处的断点
clear f:lename:lineNum #删除文件filename中行号为lineNum处的断点
delete                  #删除所有breakpoints,watchpoints和catchpoints
delete bnum             #删除断点号为bnum的断点

跳过断点

通过 info breakpoints 拿到所有设置的断点,然后ignore <breakpointNum> <times> 可以多次跳过断点

变量查看

在 gdb 中通过 print 的方式来打印变量内容

打印格式1

print [_Expression_]  
print $[_Previous value number_]  
print {[_Type_]}[_Address_]  
print [_First element_]@[_Element count_]  
print /[_Format_] [_Expression_]

此处需要注意,Format 可以包含:

Format

  • o - octal
  • x - hexadecimal
  • u - unsigned decimal
  • t - binary
  • f - floating point
  • a - address
  • c - char
  • s - string

内存查看

x [_Address expression_]  
x /[_Format_] [_Address expression_]  
x /[_Length_][_Format_] [_Address expression_]  
x

Last modified on 2024-09-17