GDB全称是 GNU Project Debugger,是GNU工程专用调试器。当前最新版本为 7.10.1,可以在官网下载本系统使用的是 TDM-GCC 4.9.2 中自带的 7.6.1 版本。透过 GDB 可以实现 Ada, C, C++, Objective-C, Pascal 等等众语言的程序调试。调试方式可以是本地运行调式,远程运行调试也一样行,官网简明功能描述是这样的:
执行 GDB 调式程序,它会以控制台界面显示一些状态信息,不用复杂的 GUI,它的功能一点也不比 WinDBG 弱。
>gdb
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
.
进入 GDB 后,使用 exec 命令来加载待调试的目标程序,并使用 file 命令来加载调试符号文信息件:
(gdb) exec overload.exe
(gdb) file overloadApp.o
Reading symbols from C:\c\src\overload\Debug\overloadApp.o...done.
当然,这可以在运行 GDB 前用一条命令来完成:
gdb overload
有了调试信息后,就可以使用一些和调试直接相关的操作了,首先是列表命令 l,使用它可以列出指定行号的源代码内容。
(gdb) l
1 /***************************************************************
2 * Name: overloadMain.cpp
3 * Purpose: Code for Application Frame
4 * Author: Jimbo ([email protected])
5 * Created: 2016-01-31
6 * Copyright: Jimbo (www.here.com)
7 * License:
8 **************************************************************/
9
10 #include "overloadMain.h"
列表命令默认显示上下5行,可以透过 set 命令改变 listsize 这个值,set 甚至还可以改变寄存器的值:
set listsize count
set
通常调式自己在开发的程序是有目的地将断点设定在指定的代码行、函数或类成员中,因此断点命令可以有多种格式,它支持命名空间前缀也支持中断的条件设置:
(gdb) b 84
Breakpoint 1 at 0x42d: file C:\c\src\overload\overloadMain.cpp, line 84.
(gdb) b overloadMain.cpp:26
Breakpoint 2 at 0x0: file C:\c\src\overload\overloadMain.cpp, line 26.
(gdb) b overloadFrame::overloadFrame
Breakpoint 3 at 0xdc: file C:\c\src\overload\overloadMain.cpp, line 68.
(gdb) b overloadMain.cpp:wxbuildinfo
Breakpoint 4 at 0x0: file C:\c\src\overload\overloadMain.cpp, line 26.
条件断点设置的格式参考:
b file.cpp:26 if var == value
对于已经设置的断点可以使用 info b 命令来检查,或者透过 clear 来清除断点。
(gdb) info b
(gdb) clear 26
(gdb) clear wxbuildinfo
还可以设置观测点来实现程序中断,观测点有 watch 指定的表达式有变化就中断, rwatch 指定表达式被读取时中断, awwatch 指定表达式被赋值或有写入动作时中断。 info 是一个多用命令,在这可以用它来显示已设置观测点信息:
info watchpoints
开始执行程序时有一组命令用来控制执行过程,run 启动程序,next 单步执行跳过函数,step 单步执行进入函数,until 用来退出循环体,finish 用来完成函数调用,continue 则断续执行直到下一个中断为止。 GDB 还提供了两个专门执行单条机器指令的命令,stepi 和 nexti,单步跟踪一条机器指令,用来分解代码。 命令 print 除了用来显示信息还可以用改变程序的数据,而 jump 命令则可以用来改变运行流程,或者使用 call 来强制执行。
进入调式状态,可以透过另一组命令来查看硬件内部状态,breacktrace 用来查看堆栈信息,frame 用来选择定栈层并结合 info frame 命令来查看堆栈层的细节,比如压栈的内容,堆栈层号越小就越接近当前执行的控制点。up 和 down 用来上下移动栈层并指定偏移值,它们有对应的 silent 方式,select-frame、up-silently、down-silently,这样可以避免在选择栈层时在控制台上显示多余的信息。还有 return 可以用来在堆栈中执行返回的动作。
寄存器的查看则是通过 info 命令实现的,结合 set 命令僦可以实现寄存器的读写:
info register
set $eax=0
以上这些命令都有简写形式,比如 breaktrace 简写为 bt,register 简写为 reg,这样可以方便使用。另外回车功能可以用来重复上一次的动作。要结束调试,直接使用 quit 命令。
GDB 作为一个代码级别的调试程序,它的源代码搜索功能也很强。使用 directory 命令来添加代码目录,如果不给它指定目录或指定已经添加过的目录,则会将目录从搜索路径列表中移除。而实际上更强大的目录搜索功能是替换规则,考虑一个程序编译完后,代码的路径被移动过,该怎样来找到源代码呢?使用PATH环境变量吗?NO,GDB不会做这样的蠢事。一个方法是将源代码也移动到相应的位置,绝对的或相对的路径,GDB它提供了一个路径替换规则来解决这个问题,如:
dir C:\\wx281\\src
set substitute-path ../../include C:\\wx281\\include
set substitute-path ../../src C:\\wx281\\src
这两条命令就是用来将系统已经安装好的 wxWidgets 代码映射到程序的调试信息中,GDB只要一看到 ../../include
这样的路径引用时,就会到 C:\\wx28\\include
目录下找源代码了。使用以下命令可以查看或修改源代码搜索路径、替换规则:
dir
show directories
show substitute-path
unset substitute-path [path]
实测中,发现 substitute-path 并没有官方说得那样有效,是根本就没有作用,不知道版本有没有兼容问题。所以我还是取了一下巧,在调试程序时,经常会遇到使用相对路径的情况,所以,特意添加了假子目录的路径,这样在引用相对目录时刚好可以抵消点号:
C:/wx281/src/faked
另外程序可能需要读取一些资源文件,如图片,当使用相对路径时,就可能因为工作目录设置问题导致加载资源不成功能。
cd 命令就可以解决这个问题,正常界面:
那么上面的内容写作 GDB 命令行运行的方式就是这样的,-args 表示要给被调试的程序传递参数 anything:
gdb --directory="C:\CodeBlocks\wx281\src;C:\CodeBlocks\wx281\src\fake"
-ex="set substitute-path ../../include C:\\CodeBlocks\\wx281\\include"
-ex="set substitute-path ../../src C:\\CodeBlocks\\wx281\\src"
-args overload.exe anything
清楚GDB功能及使用后,再来配置 CodeBlocks 显得相当顺手啦。当然GDB的功能远不只前面提到的这部分,有兴趣可以参考官方手册的更多内容。
通过 Settings -> Debugger 打开 CodeBlocks 调试器设置界面,选择 GDB 的配置,并在 Arguments 处输入以下内容,这里使用了全局变量 #wx281 指向 wxWidgets 2.8.12 的安装目录,另一个变量 $(TARGET_OUTPUT_DIR) 则指向了编译器生成的结果的输出目录:
--directory=$(#wx281)/src --cd=$(TARGET_OUTPUT_DIR)
GDB官方下载
GDB使用大全
GDB官方文档
Windbg调试命令详解