GDB 学习笔记

184 阅读3分钟

GDB 常用命令

info

  • info process 显示进程
  • info thread 显示线程
  • info b 显示所有断点
  • info locals 显示当前临时变量
  • info var 显示全局变量及静态变量
  • info watch 显示watch状态
  • info display 显示autodisplay的信息

debug

  • b+functionname 设置断点
  • set breakpoint pending on 可以避免动态载入库的断点提示
  • clear+b 删除断点
  • del +id 删除断点 www.jianshu.com/p/169e84a79…
  • r/run 重启程序
  • start 重启程序并且停在main
  • c/continue 继续运行到下一个断点
  • s/step 跳进函数
  • n/next 单步执行
  • finish 结束当前函数
  • q/quit 退出程序
  • p+变量名 打印变量
  • return 强制当前函数返回
  • bt 显示调用栈
  • up/down 可以在不同的frame之间切换
  • watch+变量名 当这个变量发生变化时,程序会听着在这里
  • display+变量名 每次运行结束时,自动打印,省去了每次print
  • print+变量名 检查变量
  • call/print+ functions 强制调函数, 两者有细微的差别
  • list 查看当前位置的代码
  • set var XX=xx 将某个变量强制赋值

layout

  • ctrl+x,ctrl+a 显示源代码
  • ctrl+x, o 可以将焦点在src与调试窗口之间切换
  • refresh/ctrl+l 乱码刷新
  • layout src 源代码模式
  • layout asm 汇编模式
  • layout regs 寄存器模式
  • layout split,ctrl+x,1,ctrl+x,2 可以组合模式

跟踪子进程

  • set follow-fork-mode child
  • set follow-fork-mode parent
  • 由于gdb只能跟踪一个进程,在程序进程fork的时候,需要选择跟踪父进程还是子进程,选择其中一个(默认父进程 ),另外一个是行为是自由/不受控的。
  • 这个可以动态改变,比如程序不断fork到某个child的时候,再设置为parent

attach进程

  • gdb -p pid
  • gdb && attach to pid
  • 可能还需要插入可执行程序的路径。

处理signal

  • info handle 可以看到signal的处理。
  • handle SIGINT stop pass 可以进入ctrl c的函数
  • stop: 当收到这个信号时,gdb是否stop/break
  • print: 当收到这个信号时,gdb是否print message
  • pass: gdb 是否允许这个signal传送到相关的程序(这关系到信号处理函数是否被调用)

当软件重新编译的时候,gdb的r可以自动运行新程序,但是gdb调试的时候,源文件不会自动重载,需要运行directory命令。 Reference: www.jianshu.com/p/6cdd79ed7…

远程debug

server

  • gdbserver host:2345 exe arg1 arg2 client
  • gdb exe
  • target remote hostip:2345

gdb 可以控制程序执行流程,但是输出还是在target的机器上。 gdb server并没有使用安全协议,不能再开放网络使用 gdb server 不需要符号,可以运行strip的二进制,但是gdb client 需要。

自启动命令

  • ~/.gdbinit
  • ./.gdbinit
  • 可以通过-x指定其他额外的文件,上面两个照样执行
  • -nx 可以禁止脚本的自动运行
  • 防止恶意的脚本执行,需要配置add-auto-load-safe-path /yourdir/.gdbinit来自动加载local的gdbinit,或者使用set auto-load safe-path /关闭安全检查。 sourceware.org/gdb/onlined…

符号文件

符号文件就是建立(源代码<->汇编指令)的关系,这样便于调试。在windows里为pdb文件,linux里面与二进制集成在一起。 但是符号文件,直接只是映射关系,不包括源代码,例如:0x12345 -> function at main.cpp:10.调试的时候,还是需要源文件的。

lx-symbols

(重新)载入 kernel 以及 loaded module的符号文件。

  1. 这个moudule需要已经load,这里才会加载它的符号文件。对于gdb而言,需要先在target上执行insmod abc.ko,然后执行lx-symbols ../
  2. 会对指定目录进行递归检查

dir /directory

可以重新指定目录,并且刷新。