关于gdb

GDB全称GDB Debugger。GDB具备各种调试功能,使用GDB的调试人员可以查看及修改程序的内部变量值。

1. 绑定进程

gdb <bin> # GDB运行一个二进制,用于调试使用

gdb attach <pid> # 绑定正在运行的进程,原则上禁止直接attach线上进程

2. 查看代码

2.1 查看程序代码

 dir <source_directory> # 添加cpp原文件目录

 l # 默认显示暂停处代码,一直执行l会向下滚动显示

 l <function> # 显示函数代码

 l <file:function> # 显示文件中某函数代码

 l <file:line> # 显示文件中指定行数代码

2.2 查看汇编指令

 disass # 显示当前汇编指令

3. 断点

3.1 断点设置

> b <file:line> # 设置文件中某行断点

> b <file:function> # 设置文件中某函数断点

> b <namespace::class::function> # 设置某类的成员函数断点

> b <location> <thread-id> # 设置某个线程在某处的断点

> b <location> if <condition> # 设置某处的条件断点

3.2 断点查看

 info b # 查询所有断点

3.3 断点删除/启用/禁用

> d <break-id> # 删除某断点

> disable <break-id> # 禁用某断点

> enable <break-id> # 启用某断点

3.4 断点设置自动执行命令

 command <break-id>

 p <var> # 运行到断点处时自动打印变量<var>

 end

4. 打印变量

4.1 打印普通变量

print

> p <expr> # 打印变量<var>
> p <var>=<value> # GDB过程中更改某个变量的值

display

display和print区别在于,display会一直打印某个值

> display <expr> # 打印某个变量或表达式,expr 表示要查看的目标变量或表达式

> display/fmt <expr> # 参数 fmt用于指定输出变量或表达式的格式

/fmt

功 能

/x

以十六进制的形式打印出整数。

/d

以有符号、十进制的形式打印出整数。

/u

以无符号、十进制的形式打印出整数。

/o

以八进制的形式打印出整数。

/t

以二进制的形式打印出整数。

/f

以浮点数的形式打印变量或表达式的值。

/c

以字符形式打印变量或表达式的值。

4.2 打印protobuf message

> p <var>.DebugString() # 使用DebugString()将proto对象内部结构打印出来

4.3 打印内存地址

# n:为正整数,表示需要打印的内存单元个数

#

# f:打印格式, 如下

# - x: 十六进制

# - d: 十进制

# - u: 十六进制

# - o: 八进制

# - t: 二进制

# - a: 十六进制

# - c: 字符格式

# - f: 浮点数

#

# u: 内存单元大小,如下:

# - b: 单字节

# - h: 双字节

# - w: 四字节

# - g: 八字节

#

> x/<n/f/u> <addr> # addr: 要打印的内存地址

4.4 dump内存内容至文件

# 将start_addr至end_addr的内存内容以二进制形式dump到file文件,file文件名自定义即可

> dump binary memory <file> <start_addr> <end_addr>

4.5 打印长字符串

gdb会限制打印字符串的最大长度。使用下列命令可修改限制。

> show print elements # 显示字符串最大打印长度

> set print elements 0 # 取消字符串最大打印长度

4.6 打印CPU寄存器的值

> i r # 打印所有寄存器的值

> i r es # 打印寄存器es的值

5. 线程调试

pstack <pid> # 可事先dump某个进程下所有线程的thread id和backtrace,方便gdb调试

 info threads # 查看当前所有线程信息

 bt # 查看当前线程的backtrace

 bt full # 查看当前线程更详细的backtrace(每个栈帧上的参数)

 thread <thread-id> # 切换到某一个线程

 set scheduler-locking on # 多线程环境下,只有当前被调试线程会执行

 set scheduler-locking off # 多线程环境下,除当前被调试线程之外的其他线程也在同步执行

 set scheduler-locking step # 多线程环境下,对当前被调试线程用step调试时,其他线程不会执行;使用next调试时,其他线程也许会执行

6. 运行控制

 r arg1 arg2 ... # 重新开始运行二进制,如果需要传入参数内需要arg1 arg2...

 stop # 暂停运行

 c # 继续执行(continue)

 n # 单步执行(next),遇到函数则跳过

 s # 单步执行(step),遇到函数则跳入函数体

 finish # 运行直到跳出当前函数

 until line # 运行直到到达指定行

 call command # 运行C++命令

 shell # 进入shell模式,回到linux终端

 exit # 退出shell模式,回到gdb命令行

 set $var=XXX # 设置gdb变量

 set var=XXX # 设置程序中变量

7. 结束调试

# gdb二进制时,使用q/quit退出

 q

 quit

# gdb attach进程时,使用detach退出

 detach

8. 调试core

一般情况下,当设置了ulimit -c unlimited之后,当程序遇到异常时,会自动转储core文件(即crash时会dump core文件),方便开发者查看分析现场。

但是,如果想对一个正常运行的进程进行转储, 可使用gcore命令:

gcore <pid> # 将进程<pid>转储到core文件中

调试core文件

# 调试core文件,两个gdb命令都可

gdb bin core

gdb -c core bin

 bt full # 查看异常的backtrace

9. 代码窗口

gdb命令行中输入CTRL + X或者CTRL + A,即可调出代码窗口,再按一次退出代码窗口。

注意: 在tui模式下,无法使用方向键获取上一条或下一条命令,可使用ctrl+p和ctrl+n替代

10. 开启日志

gdb默认不开启日志。可使用如下命令开启

 set logging on # 设置gdb日志开启,gdb会在当前目录下生成gdb.txt记录gdb命令行所有输出结果,方便回溯历史。

11.一些小问题

breakpoint断点定位到指定代码库的指定文件的指定行(以coredump中的地址为准)

b lalalal/func/output/include/infer.h:1915

gdb断点不停

可以先尝试更换一下编译级别:-O2更正成-O0

但是需要记住,这里需要重新编译,不要直接用!

关于core文件的使用

首先 sudo ./setup.bash -u ./core.aa (其中参数 -u,添加路径)

接着运行:sudo gdb ./bin/llala(可执行文件) core.aa(core文件)

进入gdb之后,就可以跟踪查看bt

gdb查core

ll /home/coredumps

/opt/compiler/gcc-8.2/bin/gdb ./bin/[bin文件] /home/coredumps/[core文件]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值