GDB入门
目录
GDB(GNU Debugger)是UNIX及UNIX-like下的强大调试工具,可以调试ada, c, c++, asm, minimal, d, fortran, objective-c, go, java,pascal等语言。
基本概念
虚拟内存
参考《the linux programming interface》第六章,x86-32下一个linux进程的内存布局如下:

-
内核空间
-
文本段(text segment)
- 代码段
- 可共享
- Readonly
-
Initialized Data Segment
- 初始化的全局变量区
-
Uninitialized Data Segment(bss)
- 未初始化的全局变量区
-
Stack(栈)
- 向下增长
-
Heap(堆)
- 向上增长
-
查看程序/进程构造的几个方法
sizeobjdumppmapreadelf
常用命令
编译参数
-g
产生调试信息-O0
不进行优化处理-ggdb,增加更多的调试信息
前端显示
- DDD
- TUI
--tui
help
(gdb) help
List of classes of commands:
aliases -- User-defined aliases of other commands.
breakpoints -- Making program stop at certain points.
data -- Examining data.
files -- Specifying and examining files.
internals -- Maintenance commands.
obscure -- Obscure features.
running -- Running the program.
stack -- Examining the stack.
status -- Status inquiries.
support -- Support facilities.
text-user-interface -- TUI is the GDB text based interface.
tracepoints -- Tracing of program execution without stopping the program.
user-defined -- User-defined commands.
Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
启动
- gdb直接启动
gdb exec_namegdb –args exec_name argv[]
- gdb挂到程序
gdb attach/detachgdb –pid
- 分析
coregdb exec_name core_name
- 一些参数
--symbols <file>符号表--core <core_file>指定core文件--directory Search for source files in DIR
运行程序
-
以
gdb <exec_name>启动后,在path中搜索<program>的源文件- 用
l或者list确认是否读取到源文件
- 用
-
设置
- 参数
set argsshow args
- 运行环境
path <dir>设置程序的运行环境show pathsset environment设置环境变量show environment
- 工作目录
cd <dir>pwd
- 输入和输出
info terminal显示用到的终端模式- 重定向输出,如
run > outfile tty命令指定输入和输出的终端设备
- 参数
停止/恢复
- 类型
- 断点(breakpoint)
- 观察点(watchpoint)
- 捕捉点(catchpoint)
- 信号(signals)
- 线程停止(thread stops)
- 恢复
c(continue),命令fg命令
断点
- break 断在下一条将要执行的指令
break <function>断在函数break <linenum>指定行号break +/-offset在当前行号的前后偏移行断住break filename:linenum指定文件和行数bread *address指定的内存地址break … if <condition>- … 可以是上述的参数
condition表示条件,如break if i >0
condition <breakpoint_num> <expression>breakpoint_num对应断点号expression,新的条件表达式
info breakpoints [n]查看断点,n表示断点号
观察点
watch <expr>为表达式设置观察点,一旦值发生变化,马上停住程序rwatch [-l|-location] EXPRESSION- A watchpoint stops execution of your program whenever the value of an expression is read
awatch [-l|-location] EXPRESSION- A watchpoint stops execution of your program whenever the value of an expression is either read or written.
info watchpoints- 列出观察点
捕捉点
- 捕捉程序运行时的一些事件
- catch
(gdb) catch
List of catch subcommands:
catch assert -- Catch failed Ada assertions, when raised.
catch catch -- Catch an exception, when caught.
catch exception -- Catch Ada exceptions, when raised.
catch exec -- Catch calls to exec.
catch fork -- Catch calls to fork.
catch handlers -- Catch Ada exceptions, when handled.
catch load -- Catch loads of shared libraries.
catch rethrow -- Catch an exception, when rethrown.
catch signal -- Catch signals by their names and/or numbers.
catch syscall -- Catch system calls by their names, groups and/or numbers.
catch throw -- Catch an exception, when thrown.
catch unload -- Catch unloads of shared libraries.
catch vfork -- Catch calls to vfork.
Type "help catch" followed by catch subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
- tcatch
(gdb) tcatch
List of tcatch subcommands:
tcatch assert -- Catch failed Ada assertions, when raised.
tcatch catch -- Catch an exception, when caught.
tcatch exception -- Catch Ada exceptions, when raised.
tcatch exec -- Catch calls to exec.
tcatch fork -- Catch calls to fork.
tcatch handlers -- Catch Ada exceptions, when handled.
tcatch load -- Catch loads of shared libraries.
tcatch rethrow -- Catch an exception, when rethrown.
tcatch signal -- Catch signals by their names and/or numbers.
tcatch syscall -- Catch system calls by their names, groups and/or numbers.
tcatch throw -- Catch an exception, when thrown.
tcatch unload -- Catch unloads of shared libraries.
tcatch vfork -- Catch calls to vfork.
Type "help tcatch" followed by tcatch subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
维护停止点
clearclear <function>- clear filename:function`
deletedelete [breakpoints] [range..]- 删除指定断点
- breakpoints为断点号。如果不指定,删除所有。
- range表示断点范围,如(3-7)
disable,不删除,gdb不会在停止disable [breakpoints] [range…]
ignore <bnum> <count>- 忽略断点号为bnum的停止条件count次
enable,恢复enable [breakpoints] [range..]enable [breakpoints] once [range…]恢复一次后disableenable [breakpoints] delete [range..]恢复一次后delete
为停止点设定执行命令
- 当运行的程序被停止住时,可以让其自动运行一些别的命令,很强大的命令。
command [bnum]
… command-list …
end
如
break foo if x>0
commands
printf “x is %d\n”,n
continue
end
在函数foo中,如果x>0时断住,并自动打印x,然后运行程序
单步
-
step <N>- Argument N means step N times
- 进入函数的前提是,此函数被编译有debug信息
-
next <N>- this command does not enter the subroutine, but instead steps over the call, in effect treating it as a single source line
-
一些设置命令
set step-mode on- 程序不会因为没有debug信息而不停住
-
finish- 运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息
-
until- 运行程序直到退出循环体
-
stepi和nexti- Step one instruction exactly
信号
- gdb可以捕捉程序的所有信号
handle SIGNAL [ACTIONS]- 可以以SIG开头或不以SIG开头,可以用定义一个要处理信号的范围
- 一旦被调试的程序接收到信号,运行程序马上会被GDB停住
- actions
stop,nostop,print,noprint,pass,nopass,ignore,noignore.
- info signals,列出信号信息
- info handles
线程
info threads- 列出线程
thread <N>- 切换线程
thread apply all bt- 打印所有线程的堆栈
- 可以设置断点在所有线程或者某个特定线程
break <linespec> thread <threadno> if ...break <linespec> thread <threadno>
堆栈

bt打印当前函数的调用栈信息backtrace <n>- n是一个正整数,表示只打印栈顶上n层的栈信息。
backtrace <-n>-n表一个负整数,表示只打印栈底下n层的栈信息。
- 切换栈
frame <n>up <n>- 表示向栈的上面移动n层,可以不打n,表示向上移动一层。
down <n>- 表示向栈的下面移动n层,可以不打n,表示向下移动一层。
- info frame更详细的栈层信息

info args- 打印出当前函数的参数名及其值。
info locals- 打印出当前函数中所有局部变量及其值。
info catch- 打印出当前的函数中的异常处理信息。
查看源码
- 需要加上
-g参数 listlist <linenum>- 显示程序第linenum行的周围的源程序。
list <function>- 显示函数名为function的函数的源程序。
list –- 显示当前行前面的源程序。
list <first>, <last>- 显示从first行到last行之间的源代码。
list , <last>- 显示从当前行到last行之间的源代码。
list +- 往后显示源代码。
- 设置
set listsize <count>- 设置一次显示源代码的行数。
show listsize
<linenum> 行号。
<+offset> 当前行号的正偏移量。
<-offset> 当前行号的负偏移量。
<filename:linenum> 哪个文件的哪一行。
<function> 函数名。
<filename:function> 哪个文件中的哪个函数。
<*address> 程序运行时的语句在内存中的地址。
搜索源代码
- GDB提供源代码搜索的命令:
forward-search <regexp>search <regexp>- 向前面搜索。
reverse-search <regexp>- 全部搜索。
显示
printprint <expr>print /<f> <expr>/<f>表示显示格式x按十六进制格式显示变量。d按十进制格式显示变量。u按十六进制格式显示无符号整型。o按八进制格式显示变量。t按二进制格式显示变量。a按十六进制格式显示变量。c按字符格式显示变量。f按浮点数格式显示变量。
- expr可以是常量、变量、函数等(不支持宏)
- 几个特殊操作符
@,与数组相关,左边表示内存的起始地址,右边是要查看的长度p *array@len
- 几个特殊操作符
display,自动显示- 支持
i,显示指令 display /i $pc=> 0x403740 <main>: push %rbp
- 支持
查看内存
examine命令(简写是x)来查看内存地址中的值x/<n/f/u> <addr>- n是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
f表示显示的格式u表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes,可用下面字符取代b表示单字节h表示双字节w表示四字节g表示八字节
addr,内存地址
一些设置命令
set print address on- 打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的
set print array on- 打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔
set print elements <number-of-elements>- 数组太大,指定显示的数量
set print null-stop <on/off>- 如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。
set print pretty on- 如果打开
printf pretty这个选项,那么当GDB显示结构体时会比较漂亮
- 如果打开
set print union <on/off>- 设置显示结构体时,是否显式其内的联合体数据。
- set disassembly-flavor att /intel
- 设置汇编显示的格式
查看寄存器
info register- 可以使用print命令来访问寄存器的情况,只需要在寄存器名字前加一个$符号
disassemble/m显示源码/r以16进制显示原始指令
修改变量值
- 直接print,如
print x=4,将x赋值为4
set var
其他高级用法
- 远程调试
- 执行脚本
- gprof
- 参考gdb官方手册《debugging with gdb》
案例
小结
- 定位问题的时候,结合不同的工具进行
- 如
objdump、pmap等
- 如
- 实际开发中,日志更重要
- 日志要求提供足够的调试信息
参考
GDB: The GNU Project Debugger
GDB Tutorial
Debugging with GDB
Using the GNU Compiler Collection
gcc 编译 选项 汇总
linux进程中的内存分布
GDB调试指南

浙公网安备 33010602011771号