gdb学习

变量打印方式
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/sx/f 之类的格式可能会影响 x/w 的显示,因为它们可能会改变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  //打印字符无限制

 


gdb调试循环
假设我想查看低70次循环
for(i = 0;i < 100; i++)
watich i           监视i变量
ignore i 70         设置忽略对i的70次监视
c             跳转至第70次循环


gdb信号处理
handle SIGUSR1 nostop noprint


gdb地址调试
比如打印wstring


获取str3的地址


获取str3的大小


以十进制打印地址


拼接地址,分别为 03 77 a2 b8 拼接后为0x377a2b8


gdb汇编调试
disassemble可以展开断点函数的汇编
disassemble 地址
disassemble 函数声明
disassemble 开始地址, 结束地址
disassemble 地址加字节数
disassemble 函数声明加字节数
disassemble /m 地址或者函数声明         反汇编命令将显示与反汇编指令相对应的源代码行
disassemble /r 地址或者函数声明         显示所有反汇编指令的原始字节值
info r                      查看寄存器信息
set disassemble-next-line on           显示下一条要执行的汇编代码
si                       执行以下一步汇编
b *main+12                   在某处汇编地址断点,只能从函数声明处,通过地址偏移实现。例如

除了disassemble可以展开汇编之外,display,x/i等之类的也可以展开汇编,

display /20i function_name/addr   display展开main函数的前20行汇编,函数名和地址都行

比如用x/i展开汇编

x/10i  function_name/addr  展开main函数的10行汇编 ,函数名和地址都行

 
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&


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


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


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打印方式自己研究吧


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

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