gdb用法

gdb用法

gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。

  • GDB调试一定要是可执行文件而不是.c文件

gdb调试具体命令:

gcc - g 源文件.c -o 目标文件

列文件清单

List

(gdb) list line1,line2

执行程序

  • run:使用你给予前一条 run 命令的参数(可加参数
  • set args aa bb (传参数)
  • show args(查看其缺省参数的列表。 )

显示数据

  • 利用 print 命令可以检查各个变量的值。

(gdb) print p (p是变量名)

  • whatis 命令可以显示某个变量的类型

(gdb) whatis p

  • l 对程序中函数的调用

(gdb) print find_entry(1,0)

  • l 数据结构和其他复杂对象

(gdb) print *table_start

$8={e=reference=’\000’,location=0x0,next=0x0}

  • l 值的历史成分

(gdb)print $1 ($1 为历史记录变量,在以后可以直接引用 $1 的值)

  • l 人为数组

查看内存中在变量 h 后面的 10 个整 数,一个动态数组的语法如下所示:

​ (gdb)print h@10

$13=(-1,345,23,-234,0,0,0,98,345,10)

  • 改变变量名示例:

(gdb) set variable <变量> = <表达式>:将变量的值设定为指定表达式的值。

​ 例如 set variable x=10

(gdb) print <变量> = <表达式>:查看并修改变量

断点(breakpoint)

break 命令(可以简写为 b)可以用来在调试的程序中设置断点,该命令有如下四种形式:

  • break line-number 使程序恰好在执行给定行之前停止。

  • break function-name 使程序恰好在进入指定的函数之前停止。

  • break line-or-function if conditio如果condition(条件)是真,程序到达指定行或函数时停止。

  • break routine-name 在指定例程的入口处设置断点

如果该程序是由很多原文件构成的,你可以在各个原文件中设置断点,而不是在当前的原文件中设置断点,其方法如下:

(gdb) break filename:line-number

(gdb) break filename:function-name

要想设置一个条件断点,可以利用 break if 命令,如下所示:

(gdb) break line-or-function if expr

例:

​ (gdb) break 46 if testsize==100

断点的管理

显示当前 gdb 的断点信息:

(gdb) info break

删除指定的某个断点:

(gdb) delete breakpoint 1

该命令将会删除编号为 1 的断点,如果不带编号参数,将删除所有的断点

禁止使用某个断点

(gdb) disable breakpoint 1

该命令将禁止断点 1,同时断点信息的 (Enb)域将变为 n

允许使用某个断点

enable breakpoint 1

该命令将允许断点 1,同时断点信息的 (Enb)域将变为 y

清除原文件中某一代码行上的所有断点

(gdb)clean number

变量的检查和赋值

  • whatis: 识别数组或变量的类型

  • ptype: 比 whatis 的功能更强,他可以提供一个结构的定义

  • set variable: 将值赋予变量

  • print: 除了显示一个变量的值外,还可以用来赋值

单步执行

next 不进入的单步执行

step 进入的单步执行

finish 如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令 finish

函数的调用

call name 调用和执行一个函数(name:函数名)

finish 结束执行当前函数,显示其返回值(如果有的话)

命令的历史

为了允许使用历史命令,可使用 set history expansion on 命令

(gdb) set history expansion on

GDB 多线程

info threads

显示当前可调试的所有线程

thread ID

切换当前调试的线程为指定 ID 的线程。

break thread_test.c:123 thread all

在所有线程中相应的行上设置断点

thread apply ID1 ID2 command

让一个或者多个线程执行 GDB 命令 command。

thread apply all command

让所有被调试线程执行 GDB 命令 command。

set scheduler-locking off|on|step

off 不锁定任何线程,也就是所有线程都执行,这是默认值。

on 只有当前被调试程序会执行。

step 在单步的时候,除了 next 过一个函数的情况(这其实是一个设置断点然后

continue 的行为)以外,只有当前线程会执行。

p用法总结

  1. print 操作符
    @
    是一个和数组有关的操作符,在后面会有更详细的说明。
    ::
    指定一个在文件或是一个函数中的变量。
    {}
    表示一个指向内存地址的类型为type的一个对象。

  2. 察看内容
    全局变量(所有文件可见的)
    静态全局变量(当前文件可见的)

局部变量(当前Scope可见的)

如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量。如果此时你想查看全局变量的值时,你可以使用“::”操作符:
file::variable
function::variable
eg:
查看文件f2.c中的全局变量x的值:
gdb) p ‘f2.c’::x

注:如果你的程序编译时开启了优化选项,那么在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况。对付这种情况时,需要在编译程序时关闭编译优化。GCC,你可以使用“-gstabs” 选项来解决这个问题。

  1. 察看数组
    (1)动态数组:
    p array@len
    array:数组的首地址,len:数据的长度
    eg:
    (gdb) p array@len
    $1 = {2, 4, 6, 8, 10}

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

  2. 输出格式
    x 按十六进制格式显示变量。
    d 按十进制格式显示变量。
    u 按十六进制格式显示无符号整型。
    o 按八进制格式显示变量。
    t 按二进制格式显示变量。
    a 按十六进制格式显示变量。
    c 按字符格式显示变量。
    f 按浮点数格式显示变量。
    eg:
    (gdb) p i

$23 = 101 ‘e’

  1. 察看内存
    使用examine(简写x)来查看内存地址中的值。语法:
    x/
    n、f、u是可选的参数。
    (1)n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
    (2)f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
    (3)u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
    eg:

x/3uh 0x54320 :从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。

  1. 察看寄存器
    (1)要查看寄存器的值,很简单,可以使用如下命令:
    info registers
    (2)查看寄存器的情况。(除了浮点寄存器)
    info all-registers
    (3)查看所有寄存器的情况。(包括浮点寄存器)
    info registers
    (4)查看所指定的寄存器的情况。
    寄存器中放置了程序运行时的数据,比如程序当前运行的指令地址(ip),程序的当前堆栈地址(sp)等等。你同样可以使用print命令来访问寄存器的情况,只需要在寄存器名字前加一个

  2. display自动显示的变量
    (1)格式:display[/i|s] [expression | addr]
    eg:
    display/i

disable display
enable display
disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。

info display
查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable。

  1. 设置
    (1)set print address
    set print address on
    打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。
    (2)set print array
    set print array on
    打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。
    (3)set print elements
    这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。
    (4)set print null-stop
    如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。
    (5)set print pretty on
    如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。如:
    $1 = {
    next = 0x0,
    flags = {
    sweet = 1,
    sour = 1
    },
    meat = 0x54 “Pork”
    }

(6)set print union
设置显示结构体时,是否显式其内的联合体数据。
(7)set print object
在C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值