gdb笔记

1, 启动调试程序及命令

// 方法一
gdb test.exe
// 方法二,先进入gdb
gdb
// 使用file命令
file test.exe
// 随后使用run命令即可调试程序

2, 断点

// 运行到某行停止运行
break 行号
// 程序进入指定功能函数时停止运行
break 函数名称
// 符合if语句条件时,运行到指定位置停止运行
break 行号/函数名称 if 条件

在这里插入图片描述

  • 完成需要的调试后,可以使用continue命令继续执行程序。由于程序设置了两个断点,因此continue会运行到第二个断点处停住,接着继续调试。

  • 在使用断点时,enable命令可以恢复暂时不起作用的断点(如已经运行了第二个断点,但想反过来运行第一个断点)。

    // 恢复多个断点采用行号空格隔开
    enable 1 13
    
  • 使用disable命令设置断点失效,使程序继续使用,不在此断点处停住(例如设置了两个断点,当执行到第一个断点时,使用disable使第二个断点失效,程序将不在第二个断点处停留)。

  • 使用delete命令,clear命令清除断点,区别在于clear清除断点需要标明断点所在行号,delete需要标明断点的编号。采用clear清除断点时,GDB调试工具会给出提示信息,delete则不会给出提示。

    在这里插入图片描述

3, 检查数据的功能及命令(print,display)

printf命令:
  • 打印变量或表达式的值。

    print 变量名/表达式
    
  1. 执行完命令会通过’$'显示出这是在调试过程中第几次使用print命令,就是显示出当前序列号。

  2. " " 如果作为 p r i n t 命令的参数 , 表示给定序号的前一个序号 , " "如果作为print命令的参数,表示给定序号的前一个序号," "如果作为print命令的参数,表示给定序号的前一个序号,"$"表示给定序号的向前第二个序号

    // 表示给定序号的前一个序号
    print $
    // 表示给定序号的向前第二个序号
    print $$
    

    如,当前给定序号是9,那么print $表示序号为8时显示的数据,print $$ 表示为7时的数据

  • print可以用于对变量赋值,并可以打印内存中从某一部分开始的一块连续空间的内容,表达形式如下:

    // 变量赋初值
    print vari = 7
    // 打印连续空间数据
    print 开始表达式@要打印的连续空间大小
    

在这里插入图片描述

display命令:

该命令用于显示表达式的值。与print不同的是,使用该命令每当程序运行到断点处,都会显示表达式的值。

在这里插入图片描述

如上所示,每当运行到断点处时,都可以观察到之前变量值的变化。

  • 可以使用undisplay,enable display,delete display命令设置要显示的表达式暂时无效,即在下一次运行到断点时,不显示此表达式的变量值。

  • 使用enable display将暂时失效的表达式恢复。

查看变量或函数的类型(whatis,ptype)

检查表达式的信息,包括表达式的值和表达式的数据类型,可以使用whatis命令和ptype命令实现,两者的区别在于whatis命令只显示数据类型,而ptype命令可以给出类型的定义(如class类)。
在这里插入图片描述

修改变量的值(set)

当程序中存在一个循环体,循环次数很大的时候,在调试过程中需要观测循环变量等于某一较大值时的状态时,此时就会派上用场,可以使用set命令修改这个循环变量为需要的值。这是set命令除显示数据之外的另一功能,
在这里插入图片描述

查看内存(x)

可以查看内存地址中的值。

x/<n/f/u> <addr>
  • addr为起始地址。
  • n为一个整数,表示显示内容的个数(向后显示几个地址的内容,数组)。
  • f代表输出的格式:
    1. x: 十六进制整数格式
    2. d: 有符号十进制整数格式
    3. u: 无符号十进制整数格式
    4. o: 八进制整数格式
    5. t:二进制整数格式
    6. c: 字符格式
    7. f: 浮点数格式
  • u代表从当前地址开始向后请求的字节数。默认4字节,当指定了字节长度后,会从指定内存地址开始读写指定字节,并当作一个值取出来。
    1. b: 字节(byte)
    2. h: 双字节数值
    3. w: 4字节数值
    4. g: 8字节数值

例如n,f,u,addr可以理解为从addr地址开始以f格式显示n个u数值。

在这里插入图片描述

使用观察窗口功能及其命令(watch)

在使用观察窗口时,需要设置监视点,用于监视某个表达式或变量,当表达式或变量的值被读或被写时让程序停住。

  • watch命令 :为表达式(变量)设置一个监视点,用于监视被写的内容,一旦表达式值(或变量值)有变化,就立即停住程序。
  • rwatch命令 :用于监视某个表达式(变量)被读,当表达式值(变量值)被读取时,就停住程序
  • awatch命令 : 用于当表达式(变量)的值被读或被写时,停住程序。
  • info watchpoints命令 : 用于列出当前所设置的所有监视点的相关信息。

在这里插入图片描述

检查栈信息功能及其命令

可通过命令查看栈信息,所谓栈层信息,是指栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。有以下语句:

  • backtrace: 简写为bt,用于显示当前的函数调用栈的所有信息。bt n,若n为正整数,代表只显示栈顶上n层的栈信息,若n为负整数时,表示只显示栈底下n层的栈信息。

  • frame n: 简写为f n,其中n为从0开始的整数,表示栈中的层编号,用于显示第n层栈信息,若没有n值,可用于显示当前栈层的信息。

  • up n: 向栈底方向移动n层,若没有n,则表示向栈底方向移动一层。

  • down n:表示向栈顶方向移动n层。

  • info frame:简写为info f,可用此命令显示更为详细的栈层信息(被调用函数地址,当前函数使用编程语言,函数参数地址及值…)。

  • info args:用于显示当前函数的参数名及值。

  • info locals:用于显示当前函数局部变量及值。

  • info catch:用于显示当前函数中的异常处理信息。

在这里插入图片描述

检查源代码功能及其命令

查看源代码的功能有如下几种,显示源代码,搜索源代码,查看源代码的所在路径以及查看源代码的内存。

  • list: 不加任何参数表示显示当前行后面的代码

  • <+> : 显示当前行号后面的代码

  • <-> : 显示当前行号前面的代码

  • < n > : 显示程序第n行周围的代码

  • : 显示函数名为function的功能函数代码

  • <first,last> : 显示从第first行到第last行之间的代码

  • <,last> :显示当前行到last行之间的代码

  • < filename:n> : 显示文件名为filename的文件的第n行的代码

  • <filename : function> : 显示文件名为filename的文件中的函数名为function的函数的代码

    默认情况,list一次会显示10行。可以通过如下命令设置显示的代码行数。

  • set listsize< count> : count为行数,可设置每次显示源代码的行数

  • show listsize : 可查看当前显示源代码的行数设置

在这里插入图片描述

查看源代码的内存

info line可查看程序在运行时所指定的源代码的内存地址,info line后跟参数可以是行号,可以是函数名。

可以使用disassemble查看源代码当前执行时的机器码(汇编语言代码)。

在这里插入图片描述

改变程序的运行功能及其命令

程序运行过程中,可以根据需要在GDB中动态改变程序正常的运行顺序,可以通过跳转语句或修改变量值的方式,改变程序的运行方向。

set

减少执行的次数,直接运行到变量值为某值时的语句。

需要注意的是: 使用set改变变量值时,若在程序中有一个变量为width,恰巧使用set命令改变width变量的值时,则会出现错误提示,因为set width是GDB中的一个命令。为了避免此种情况,在使用set改变变量值时,尽量使用set var命令后面加上为width赋值的表达式。

改变变量值可以改变程序的运行顺序,通常应用在循环语句中,提前走出循环或者查看循环中变量为某值时的状态。然而,在想要从一个分支跳到另一个分支时,无法使用set改变变量值的方法可以使用set的如下命令更改跳转执行的地址,如:

set $pc=0x400531
jump

更改执行的地址,可以跳转到指定地址的代码处。

任意跳转,打乱执行的顺序,原理也是改变当前寄存器中的值。

jump <file:line> // line为文件file的行号,代表跳转到此行开始运行
jump <addr>		 // addr为代码所在行的地址,代表跳转到地址为addr处的语句开始执行

在使用jump命令进行随意跳转时,会忽略正常运行顺序的语句,此种方式进行调试,运行出来的结果可能会出现错误或不是正确的输出结果,因此在使用jump命令调试时要谨慎。

在这里插入图片描述

return

return命令用于快速返回一个函数的返回值,当调试进入一个功能函数时,若没有必要将函数中的所有语句都执行,可以使用return命令,快速跳出这个函数,并带回函数的返回值,忽略函数中还没有执行到的语句。

在这里插入图片描述

使用return,可以使函数返回一个指定表达式的值,

return <exp> // 将表达式的值作为函数返回值
call

用于显示表达式的值,若表达式中是函数名,那么起到的作用就是强制跳转到该函数,并显示函数的返回值。若函数无返回值(void),那么就不显示。

call <exp>	// 显示表达式的值,或显示函数的返回值

print也可以实现显示表达式值的功能,同样,若表达式为函数名,则显示函数的返回值;若函数无返回值,则显示void。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值