gdb学习

gdb一些简单的命令
start                               //开始调试
n                                   //一条一条执行
step/s                              //跟n不同的是,如果是函数,会进入函数
backtrace/bt                        //查看函数调用栈帧
info/i locals                       //查看当前栈帧局部变量
frame/f                             //选择栈帧,再查看局部变量
print/p                             //打印变量的值
finish                              //运行到当前函数返回
set var sum=0                       //修改变量值
list/l 行号或函数名                   //列出源码
display/undisplay sum               //每次停下显示变量的值/取消跟踪
break/b 行号或函数名                  //设置断点
continue/c                          //连续运行
info/i breakpoints                  //查看已经设置的断点
delete breakpoints 2                //删除某个断点
disable/enable breakpoints 3        //禁用/启用某个断点
break 9 if sum != 0                 //满足条件才激活断点
run/r                               //重新从程序开头连续执行
watch input[4]                      //设置观察点
info/i watchpoints                  //查看设置的观察点
input                               //打印存储器内容,b–每个字节一组,7–7组
disassemble                         //反汇编当前函数或指定函数
si                                  //一条指令一条指令调试 而 s 是一行一行代码
info registers                      // 显示所有寄存器的当前值
x/20 $esp                           //查看内存中开始的20个数
set print pretty on                 //让gdb打印变量一行一行的显示,而不是一堆
set print elements 0                //打印字符无限制
变量打印方式
p/t              variable_name 以二进制打印变量
p/t              variable_addr 以二进制打印地址内容
p/a              能够以指针的方式输出变量

使用 x 命令可以将指定内存地址中的内容打印出来
命令语法:x/nfu
n                用于指定打印的数量
u                用于指定每个打印变量的长度:b(byte)一个字节,h(half-word)两个字节,w(word)四个字节,g(giant word)八个字节
f                用于指定打印的格式 可取如下值
x                按十六进制格式显示变量。
d                按十进制格式显示变量。
u                按十进制格式显示无符号整型。
o                按八进制格式显示变量。
t                按二进制格式显示变量。
a                按十六进制格式显示变量。
i                指令地址格式
c                按字符格式显示变量。
f                按浮点数格式显示变量。

GDB 的 x 命令还支持其他格式,例如:
w:用于以word为单位显示内存内容。在大多数系统上,一个word的大小是4字节
b:字节(byte)        
h:半字(half-word,通常是2字节)        
g:巨字(giant-word,通常是8字节,但在某些系统上可能是4字节)
另外x/s 和 x/f 之类的格式可能会影响 x/w 的显示,因为它们可能会改变GDB解释内存内容的方式。这主要取决于内存内容的实际解释和格式。如下
gdb调试循环
假设我想查看低70次循环
for(i = 0;i < 100; i++)
watich i                    监视i变量
ignore i 70                 设置忽略对i的70次监视
c                           跳转至第70次循环
gdb后台调试
用gdb --command=filename命令,将gdb调试命令预先存储在filename命令中
例如新建文件gdb_crash文件,里面内容如下(程序收到崩溃信号以后,打印堆栈)
handle SIGABRT stop print
handle SIGFPE stop print
handle SIGSEGV stop print
handle SIGPIPE nostop noprint
c
set logging file gdb_bt.txt
set logging on
thread apply all bt
set logging off
q
y
使用下面命令,就可以将gdb挂在后台,一直等待信号
nohup gdb -p 程序pid --command=gdb_crash&
gdb利用python扩展打印stl容器变量
首先需要获取对应的python扩展
可以直接下载(地址不一定有效)
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc+±v3/python

也可以从gcc源码中拉出来
gcc-4.8.1/libstdc+±v3/python

在linux家目录下创建一份.gdbinit文件,内容很简单,如下(/usr/share/gcc-9.3.0/python是自己的目录存放地址)
python
import sys
sys.path.insert(0, ‘/usr/share/gcc-9.3.0/python’) # python目录
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

然后启动gdb就自动加载了
利用stl-views-1.0.3.gdb打印stl容器
个人感觉,这个没有python扩展好用
stl-views-1.0.3.gdb扩展下载地址忘了网上直接搜索就好

gdb附加后执行
source stl-views-1.0.3.gdb

打印vector
pvector 变量 stl类型

打印set
pset 变量 stl类型

打印map
pmap 变量 stl类型1 stl类型2

其他的stl打印方式自己研究吧

gdb源码和代码监控分开
layout

gdb信号处理
handle SIGUSR1 nostop noprint


只运行当前线程
set scheduler-locking on


gcc发现编译出来的程序无法调试
使用其他版本的编译 -gdwarf-3 -gdwarf-1 -gdwarf-2 -gdwarf-4


硬打印vector中的数据
p *(vt._M_impl._M_start)@1
vt, 容器名字
1,第几个元素,从1开始

posted @ 2024-02-07 14:31  璀丶璨星灬空  阅读(84)  评论(0)    收藏  举报