gdb调试

https://blog.csdn.net/haoel/article/details/2879

https://blog.csdn.net/haoel/article/details/2880

https://blog.csdn.net/haoel/article/details/2881

https://blog.csdn.net/haoel/article/details/2882

https://blog.csdn.net/haoel/article/details/2883

https://blog.csdn.net/haoel/article/details/2884

https://blog.csdn.net/haoel/article/details/2885

gdb查看指定地址的内存地址的值:examine 简写 x-----使用gdb> help x 来查看使用方式
x/ (n,f,u为可选参数)
n: 需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义
f:显示格式
x(hex) 按十六进制格式显示变量。
d(decimal) 按十进制格式显示变量。
u(unsigned decimal) 按十进制格式显示无符号整型。
o(octal) 按八进制格式显示变量。
t(binary) 按二进制格式显示变量。
a(address) 按十六进制格式显示变量。
c(char) 按字符格式显示变量。
f(float) 按浮点数格式显示变量
u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示
b:1 byte h:2 bytes w:4 bytes g:8 bytes
比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。
from http://www.cnblogs.com/super119/archive/2011/03/26/1996125.html


gdb打印表达式的值:print/f 表达式
f是输出的格式,x/d/u/o/t/a/c/f

表达式可以是当前程序的const常量,变量,函数等内容,但是GDB不能使用程序中所定义的宏

查看当前程序栈的内容: x/10x $sp-->打印stack的前10个元素
查看当前程序栈的信息: info frame----list general info about the frame
查看当前程序栈的参数: info args---lists arguments to the function
查看当前程序栈的局部变量: info locals---list variables stored in the frame
查看当前寄存器的值:info registers(不包括浮点寄存器) info all-registers(包括浮点寄存器)
查看当前栈帧中的异常处理器:info catch(exception handlers)


print命令的格式是:
print xxx
p xxx
1. print 操作符
@ 是一个和数组有关的操作符,在后面会有更详细的说明。
:: 指定一个在文件或是一个函数中的变量。
{}表示一个指向内存地址的类型为type的一个对象。
(1)动态数组:
p *array@len
array:数组的首地址,len:数据的长度
eg:
(gdb) p *array@len
$1 = {2, 4, 6, 8, 10}

(2)静态数组
可以直接用print数组名,就可以显示数组中所有数据的内容了。

4. 输出格式
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
eg:
(gdb) p i
$21 = 101
(gdb) p/a i
$22 = 0x65
(gdb) p/c i
$23 = 101 'e'
常用选项:
    -symbols <file>
    -s <file>
    从指定文件中读取符号表。

    -se file
    从指定文件中读取符号表信息,并把他用在可执行文件中。

    -core <file>
    -c <file>
    调试时core dump的core文件。

    -directory <directory>
    -d <directory>
    加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。


1、程序运行参数。
    set args 可指定运行时参数。(如:set args 10 20 30 40 50)
    show args 命令可以查看设置好的运行参数。

2、运行环境。
    path <dir> 可设定程序的运行路径。
    show paths 查看程序的运行路径。
    set environment varname [=value] 设置环境变量。如:set env USER=hchen
    show environment [varname] 查看环境变量。

3、工作目录。
    cd <dir> 相当于shell的cd命令。
    pwd 显示当前的所在目录。

4、程序的输入输出。
    info terminal 显示你程序用到的终端的模式。
    使用重定向控制程序输出。如:run > outfile
    tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb

一、设置断点(BreakPoint)
   
    我们用break命令来设置断点。正面有几点设置断点的方法:
   
    break <function>
        在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。

    break <linenum>
        在指定行号停住。

    break +offset
    break -offset
        在当前行号的前面或后面的offset行停住。offiset为自然数。

    break filename:linenum
        在源文件filename的linenum行处停住。

    break filename:function
        在源文件filename的function函数的入口处停住。

    break *address
        在程序运行的内存地址处停住。

    break
        break命令没有参数时,表示在下一条指令处停住。

    break ... if <condition>
        ...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。

    查看断点时,可使用info命令,如下所示:(注:n表示断点号)
    info breakpoints [n]
    info break [n]
   

二、设置观察点(WatchPoint)
   
    观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
   
    watch <expr>
        为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
       
    rwatch <expr>
        当表达式(变量)expr被读时,停住程序。
       
    awatch <expr>
        当表达式(变量)的值被读或被写时,停住程序。
   
    info watchpoints
        列出当前所设置了的所有观察点。


三、设置捕捉点(CatchPoint)

    你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
   
    catch <event>
        当event发生时,停住程序。event可以是下面的内容:
        1、throw 一个C++抛出的异常。(throw为关键字)
        2、catch 一个C++捕捉到的异常。(catch为关键字)
        3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
        4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
        5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
        6、load 或 load <libname> 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
        7、unload 或 unload <libname> 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

    tcatch <event>
        只设置一次捕捉点,当程序停住以后,应点被自动删除。
维护停止点

上面说了如何设置程序的停止点,GDB中的停止点也就是上述的三类。在GDB中,如果你觉得已定义好的停止点没有用了,你可以使用delete、clear、disable、enable这几个命令来进行维护。

    clear
        清除所有的已定义的停止点。

    clear <function>
    clear <filename:function>
        清除所有设置在函数上的停止点。

    clear <linenum>
    clear <filename:linenum>
        清除所有设置在指定行上的停止点。

    delete [breakpoints] [range...]
        删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。


比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

    disable [breakpoints] [range...]
        disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。简写命令是dis.

    enable [breakpoints] [range...]
        enable所指定的停止点,breakpoints为停止点号。

    enable [breakpoints] once range...
        enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。

    enable [breakpoints] delete range...
        enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。
当程序被停住了,你可以用continue命令恢复程序的运行直到程序结束,或下一个断点到来。也可以使用step或next命令单步跟踪程序。

    continue [ignore-count]
    c [ignore-count]
    fg [ignore-count]
        恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示忽略其后的断点次数。continue,c,fg三个命令都是一样的意思。


    step <count>
        单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

    next <count>
        同样单步跟踪,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。

    set step-mode
    set step-mode on
        打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。

    set step-mod off
        关闭step-mode模式。

    finish
        运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。

    until 或 u
        当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。

    stepi 或 si
    nexti 或 ni
        单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码)

原文地址:https://www.cnblogs.com/erhu-67786482/p/11602195.html