返回
Featured image of post Linux 命令 —— gdb

Linux 命令 —— gdb

gdb

gdb - GNU 调试器。

调试器 (如 GDB) 的目的是允许你查看其他程序在执行时的"内部"的内容,或者程序奔溃的时候正在做什么。 GDB 可以做 4 种主要的事情来帮助你捕捉 bug:

  • 启动你的程序,指定任何可能影响程序行为的内容。
  • 使程序在指定条件下停止。
  • 检查你程序停止时,正在发生的事情。
  • 更改程序中的内容,以便你可以尝试纠正一个错误的影响并继续了解另一个错误。

你可以用 GDB 来调试 C、C++、Fortran、Modula-2 编写的程序。 使用gdb命令来调用 GDB。一旦启动,它会从中断读取命令,直到你用 GDB 命令"exit"告诉它退出。你可以用 GDB 命令help来查看帮助(不用退出 gdb)。 你可以运行没有参数或选项的 gdb ; 但是最常用的启动 GDB 的方法是使用一个或两个参数,将可执行程序指定为参数:

gdb program

您还可以从可执行程序和指定的 core 文件开始:

gdb program core

如果要调试正在运行的进程,则可以将进程 ID 指定为第二个参数:

gdb program 1234 gdb -p 1234

将 GDB 附加 (attach) 到 1234 进程(除非你由一个名字为 1234 的 core 文件,gdb 会先查找 core 文件)。 以下是一些常用的 GDB 命令:

break [file:]function
    在函数(文件)中设置断点。
    缩写:b。
    用法:
        b <行号>,如:b 8
        b <函数名称>,如:b main
        b *<函数名称>,如:b *main(在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”)
        b *<代码地址>,如:b *0x804835c。
d [breakpoint number]
    删除断点

run [arglist]
    开始你的程序(arglist是参数列表)
    缩写:r

bt
    回溯(backtrace):显示程序堆栈。

print expr
    显示表达式expr的值。
    缩写:p

c
    继续运行你的程序(在停止后,例如断电)。continue的缩写。

next
    继续下一行(在停止后);不进入函数的单步调试。
    缩写:n

edit [file:]function
    查看程序当前停止的行。

list [file:]function
    在当前停止的位置附近键入程序的文本。

step
    继续下一行(在停止后);进入函数的单步调试。
    缩写:s

i
    显示各类信息。如:i r,显示寄存器的信息

help [name]
    显示GDB命令name的信息,或有关使用GDB的一般信息。

quit
    退出GDB。
    缩写:q

有关 GDB 的完整详细信息,请参阅:A Guide to the GNU Source-Level Debugger

用法

gdb [-help] [-nh] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps]
   [-tty=dev] [-s symfile] [-e prog] [-se prog] [-c core] [-p procID]
   [-x cmds] [-d dir] [prog|prog procID|prog core]

选项

选项之外的任何参数都需要指定可执行文件和核心文件(或进程 ID)。 所有选项和命令行参数都按顺序处理。使用' -x ‘选项时,顺序会有所不同。

-help
-h  列出所有选项,并提供简要说明。

-symbols=file
-s file
    从file文件中读取符号表(symbol table)。

-write
    允许写入可执行文件和core文件。

-exec=file
-e file
    使用file文件作为可执行文件在适当时执行,并与核心转储一起检查纯数据。

-se=file
    从file文件中读取符号表并将file用作可执行文件。

-core=file
-c file
   指定core文件。

-command=file
-x file
    执行file文件中的GDB命令。(自动化?)

-ex command
    执行给定的GDB命令。

-directory=directory
-d directory
    将目录添加到路径(path)以搜索源文件。

-nh 不要执行~/.gdbinit中的命令。
-nx
-n  不要执行任何'.gdbinit'初始化文件中的命令。

-quiet
-q  "Quiet". 不要打印介绍性和版权信息。这些消息也在批处理模式下被抑制。

-batch
    以批处理模式运行。
    在执行完用-x选项指定的所有命令文件(如果不禁止,则为.gdbinit)后,以0退出。
    如果在运行命令文件中的GDB命令时发生错误,则以非0退出。
    批处理模式可用于将GDB作为过滤器运行,例如在另一台计算机上下载并运行程序;
    为了使这个更有用,消息程序正常退出。【???】

-cd=directory
    使用directory作用GDB的工作目录(而不是用当前目录)

-fullname
-f   Emacs在将GDB作为子进程运行时设置此选项。
    它告诉GDB每次显示堆栈帧时都以标准的,可识别的方式输出完整的文件名和行号(包括每次程序停止时)。
    这种可识别的格式看起来像两个'\032'字符,后跟文件名,行号和以冒号分隔的字符位置,以及换行符。
    Emacs-to-GDB接口程序使用两个'\032'字符作为信号来显示帧的源代码。

-b bps
    设置GDB用于远程调试的任何串行接口的线性速度(波特率或每秒位数)。

-tty=device
    使用device运行程序的标准输入和输出。

示例

编译并跟踪

gcc test.c -o test -g
gdb test
    <gdb命令>
    <b main>: 断点
    <b 10>: 第10行设置断点
    <d 10>: 删除第10行的断点
    <info b>: 查看断点信息
    <c>: 继续
    <n>: 下一行
    <s>: 下一行,进入函数。
    <r>: 执行
    <c>: 继续执行
    <i r>: 显示寄存器的信息
    <bt>: 显示堆栈
    <list 10>: 从第10行开始显示代码

跟踪实例

gdb sbin/nginx

# 设置程序的相关参数
> set args -p /root/nginx/test

# 主要想跟踪 nginx 的 worker 进程,因此设置跟踪 fork
> set follow-fork-mode child

# 必要的地方打上断点
> b ngx_http_log_module.c:294
> b ngx_http_log_module.c:309

# 执行
> run

# 另一个 shell,发送请求 curl localhost:xxx

# 此时 gdb 这边到达断点
# 查看调用栈
> bt

#  打印想看的变量
> p values[0]
> p values[1]
> p n
> p log->script

# 有分叉,单步调试看看
> list
> n
> n

# 重复上面的步骤,逐渐找到问题

拓展

参考

相信美好的事情即将发生。
Built with Hugo
Theme Stack designed by Jimmy