GDB学习

gdb的使用教程

在gdb下使用shell命令的方法

shell shell-command
pipe p var command| wc管道用法

进入gdb

  • 调试可执行文件
    gcc 编译的时候最好带上-g指令,这样调试器能获得很多信息,gdb a.out即可进入gdb界面
  • 调试进程
    gdb调试运行着的进程 gdb program process-id ,gdb -p process-id均可
    detach attach是可用来调试进程

给调试程序设置命令行参数

set args str str给程序设定参数
show args显示参数

修改程序用到的环境变量

set enviroment varname=val
show enviroment varname

修改程序的执行路径

  • 内部程序工作目录
    set cwd=path
    show cwd
    没设的话默认继承gdb的执行路径
  • gdb工作目录
    cd pwd是可用命令

快照回退

保存某个程序状态,方便回退到这个状态而不用再次启动程序

  • 保存快照 checkpoint

  • 显示所有快照 info checkpoints

  • 删除快照 delete checkpoint id

  • 快照回退 restart id一般而言是形如restart 3这样的,取process前面的数字哟
    在这里插入图片描述

    显示源代码

  • layout src显示c代码

  • layout asm显示程序的反汇编代码

  • 在这里插入图片描述

启动命令

start:跑到main函数
starti:跑到程序第一条指令
run or r: 直接跑到遇到断点为止
continue or c:从断点开始,直到下一个断点暂停
n:下一行代码
ni:下一条指令
c [ignore_count]执行并忽略几次断点
step走源代码的一行,它和next的区别在于next不进入调用函数
finishfin,完成一个函数
until line走到某一行才停
advance line走到某一行才停,不要求在同一个栈帧里
si,ni走过一条指令,区别在于ni不进入函数

打断点

断点类型

  • 条件断点
    例如b 10 if val==3,如果变量val==3才会暂停,要在line 10处,val必须存在。-force-condition 可要求val只在有的时候是有意义的,有的时候找不到这玩意
  • 临时断点(temp break), tbreak args只会暂停一次
  • 正则断点,顾名思议,用正则表达式匹配停止的函数rbreak regex

显示断点信息

info b,info break,info b 1,显示第1个断点信息

  • 编号
  • 类型,breakpoints,watchpoints,catchpoints
  • disposition ,keep保持,delete删除,
  • enb(enable),y能用,n不生效
  • address 地址,为断点在的内存位置,当不知道内存位置时,显示pending
  • what 告诉我们这断点在哪个文件的哪一行,如暂不知,显示名字
    下图中的test是瞎编的,永远找不到这个函数在哪
    GDB学习_第1张图片
  • 在c文件指定地方打断点
    layout src,b location,location指的是c代码的行数
    b +offsetb -offset相对当前伴置偏移几行打断点
    b filename:linenumber当有多个文件时,需在前面说明文件名
    b默认为当前位置的下一条指令

观测型断点

主要是监测一个值是否发生了变化(写入,读取,值改变),如果发生了变化,停在使它变化的地方,一般使用ide所用到的断点都是上面那种断点,在某个地方打一个断点排错,基本上也够用了,不过了解这种断点会在少数情况下带来方便,比如不知道哪个人的代码改了你的全局变量的时候,或者数据被覆盖的时候。
值改变检测

  • 观测局部变量watch localval,要求当该局部变量的函数被进入时,对全局变量则没有限制
  • 观测表达式,可由局部变量,全局变量组成,当表达式有变化时,停住watch expr.例 watch c*3.

读入检测

  • rwatch args
    读写检测
  • awatch args
    当读或写时都会触发,写时值不改变也会触发

删除断点

clear删除当前断点
clear location删除某一特定断点
delete id删除info b里num=id的断点

指定断点状态

enable/diable [breakpoints] [type] [id...]
disable breakpoints禁用所有断点
enabel breakpoints id1 id2 id3...breakpoints可以不写,使能断点
disable id1 id2 id3禁用某些断点
type:

  • once 只停一次并禁用
  • count cnt 只用cnt次并禁用
  • delete 用一次就删

可编程断点

b 7 if c==3,回车
commands

silent
p c
end

定点输出

dprintf location,template,expression[,expression...]
dprintf 3,"%d %d %d",a,c,b
可以指定printf函数

断点保存

save breakpoints file存储断点
source file使用文件中的断点

跳过一些不关注的文件和函数

skip file filename当使用step时
skip functionname跳过函数

栈帧调试

  • 显示
    backtrace or bt,显示栈栈帧,不会显示局部变量
    bt -full,显示栈帧,也显示局部变量
    bt n,bt -n一个显示最内部的n个帧,一个显示最外部的n个帧
  • 选择
    frame,f
    f [level] num,选择编号为num的帧,level可以省略
    up,显示一下个帧
    down,显示上一个帧
    f function functioname,显示该函数的栈帧
  • 输出栈帧信息
    比显示能给出更多信息
    info args输出当前栈帧的调用参数
    info frame or info f输出当前栈帧信息,后面可以跟某一栈帧
    info local or info locals显示栈帧的局部变量
    info args [-q] [-t type_regexp] [regexp],两个正则表达式,一个筛类型,一个筛名称。
    frame apply [all | count | -count | level level...] [option]... command,在栈帧上执行命令
    * all 在所有帧上执行
    * count 是一个正整数,在最内部count个帧上执行
    * +count 在最外部count个帧上执行
    * level指定层数
    * faas command, frame apply all -s command的缩写

反汇编

disassemble

  • 选项 \m,\s,混和源码和汇编,\r给出16进制
  • disas \m functionname

显示数据

print,p
p val显示变量的值 p &val显示变量地址 p *(&val)显示变量(套娃写法)
类printf式输出 例 p /x val,输出16进制,

  • x 16进制
  • d 10进制默认
  • u 无符号数10进制
  • o 8进制
  • c s f 同printf
  • a 以地址形式输出,有别于printf
  • z 前置0保留16进制
  • r raw形式
    p arr,在输出数组时,如果大小已经知晓,它能输出整个数组元素。

检查内存

examine,x默认是以\x读取,用法类p
x /nfu,n表示长度,f表示format,u表示unit size(b(1byte),h(2byte),w(4byte),g(8byte)),注意 i属于f表示反编译
x /4xg 0x7fffffffd8cc读取4个字节并以16进制显示,
x /4i $pc反编译当前指令4条
$_,$__上一次x执行的结束地址,上上次的结束地址

自动化输出

display
display /fmt expr,第次停下来都可以输出该表达式,/fmt表示格式
display /i $pc显示下一条要执行的指令
delete display id删除某条display
disable or enable display id允许或禁用某条显示
info display查看有的自动化输出条目

显示变量类型

whatis valname

改变执行状态

  • 改变变量值
    print b=4在用print显示变量的时候可以给它赋个值
    set [var] varname一般可以不写var,但有的时候有歧义则一定要带上var
  • 强制跳转到其它地方
    jump,j
    j location直接跳转到某一行
    set $pc=0x34ad直接修改寄存器的值也是ok的
  • 给程序一个信号
    暂不写
  • 提前返回
    return不给返回值
    return expr给一个返回值

调用程序里的函数

p exprexpr可以包含函数调用,函数是属于被调试程序的
call function(args..)直接调用一个函数

自定义命令语法

if 语法

define adder
	if $argc == 2	
		print $arg0 + $arg1
	end
	if $argc == 3
		print $arg0 + $arg1 + $arg2
	end
end

while 语法
loop_break,loop_continue与c里的break,continue同一功能

define adder
	set $i = 0
	set $sum = 0
	while $i < $argc
		eval "set $sum = $sum + $arg%d", $i
		set $i = $i + 1
	end
	print $sum
end

hook ,会在funcname执行前先执行,对名称有固定要求

define hook-funcname
	stats
end

执行一个文件中的gdb命令

source [-s] [-v] file
//-s表示在path中找文件
//-v会打印每一条执行的命信 verbose

你可能感兴趣的:(c++)