gdb_usage
GDB basic usage
ref. GDB User Manual
GDB是一个功能十分强大的调试工具,对于二进制分析工作非常有用。这里记录GDB的一些常见用法,如果想要了解关于GDB使用的详细信息,可以参考GDB用户手册。
Get in and out of GDB
这里先介绍如何启动GDB,可以直接在命令行中输入gdb即可启动gdb。一旦启动gdb,gdb将会从命令行中读取命令直到退出。如果想要退出,那么可以输入命令q, exit 或者直接ctrl + d 以退出。
通常都会在启动gdb时指定一个可执行文件: gdb [program]
或者也可以让gdb挂载到一个正在运行中的程序: gdb -p [pid]
或者 gdb attach [pid]
通常查看运行中的程序的方式三种:
#1. 第一种方法是使用 pidof 命令进行查看,这也是最方便的一种方法,需要注意的是在命令行中是可以通过反引号进行命令的嵌套的,比如先要让gdb挂载到一个名为 host 的程序上,那么可以直接使用: gdb attach `pidof host`
#2. 第二种方法,如果是在命令行中启动目标程序,那么可以在命令后面加上一个 & 符号,那么shell在执行目标程序之前就会先打印出目标进程的pid。
#3. 第三种方法是使用ps 查看当前正在执行的所用进程。
如果想要在GDB中执行shell命令那么,可以通过以下的方法执行shell命令:
shell [comman-string]
,或者
![command-string]
这在使用gdb调试查看目标进程的内存空间分布(cat /proc/<pid>/maps)时非常有用。
如果想要将gdb命令的输出通过管道作为shell命令的输入的话,那么可以使用下面的命令:
pipe [command] | [shell_command]
,或者
|[command] | [shell_command]
可以使用gdb变量$_shell_exitcode以及$_shell_exitsignal来检查上一次通过shell或者pipe命令执行的shell命令的退出状态。
如果想要了解gdb中某个命令的使用方法,可以在gdb中输入help命令来获取帮助,也可以使用help [command]
来了解某个gdb命令的使用方法。
Running Programs Under GDB
在GDB中,可以直接使用命令 run
或者 r
启动目标程序。
如果指定目标程序的命令行参数,环境变量,工作目录以及标准输入输出,那么可以用下面的方法在运行程序之前指定这些选项:
- 命令行参数:在GDB中,可以将
run
指令的参数作为目标程序的命令行参数,或者使用set args
命令来设置命令行参数 - 环境变量:可以使用GDB命令
set environment
或者set env
来设置环境变量,然后使用unset environment
或者unset env
命令来取消环境变量,比如使用命令set env VARNAME = value
就会设置一个名为 “VARNAME” 取值为 “value” 的环境变量 - 工作目录:可以使用GDB命令
set cwd
来指定工作目录,如果没有指定工作目录,将会继承GDB的工作目录 - 标准输入输出:目标程序的标准输入输出和GDB的标准输入输出是在同一个设备上进行的,也就是说目标程序的输出和GDB的输出会在同一个终端上显示,也可以在执行
run
指令时重定向输入和输出,例如run > outputfile
就可以将目标程序的输出重定向到outputfile文件中。
需要注意的是,虽然能够在GDB中进行标准输入输出的重定向,但是不能够使用管道将目标程序的输出传递到另一个程序中。如果尝试这样做,GDB可能会调试另一个程序,而不是你想要调试的目标程序。
如果想要检查这些选项的信息,那么可以使用GDB中的 info
或者 show
命令来查看。
其中 info
指令用于描述程序的状态。比如,可以使用 info args
来查看传递给函数的参数,也可以使用 info registers
来列出当前正在使用的寄存器的值,或者使用 info breakpoints
来查看设置了哪些断点。如果想要了解 info
指令的更多用法,可以使用 help info
进行查看。
而相较于 info
指令,show
指令则是用于描述GDB自身的状态,可以使用 show
命令来查看所有由 set
指令所设置的选项,比如 show env
来查看设置的环境变量。
如果想要查看所有可以使用 set
命令设置的选项,那么可以使用不带参数的show
命令或者 info set
来查看,这两个命令的输出都是一样的。
Stopping and Continuing
在GDB中有三种情况可以让程序停止运行:
- breakpoint: 当程序运行到设置断点的地址后,将会停止运行;
- watchpoint: 当某个表达式的值改变时,程序会停止运行,这种断点有时也被称为数据断点;
- catchpoint: 当发生某种类型的事件时,程序会停止运行,比如程序抛出某个exception或者加载共享库时;
这三种断点需要使用不同命令来进行设置。