程序员开发实例大全宝库

网站首页 > 编程文章 正文

GDB使用总结

zazugpt 2025-03-05 23:48:34 编程文章 76 ℃ 0 评论

启动gdb

  • 调试可执行文件:gdb
  • 调试core文件:gdb
  • 调试正在运行的程序:gdb -p
  • 指定源文件的路径:gdb ... -d

退出gdb

  • 从gdb命令行中退出:quit / Ctrl-D

调试命令

  • 查看代码
列出源代码:list(l)
	列出当前的源代码:l
	列出代码时向上走:l -
	列出代码时向下走:l +
	列出某一行的源代码:l 
	列出某个函数的源代码:l (注意调试c++程序的时候,必须是file:namespace::classname::func_name)
	列出某个区间的源代码:l , 
	列出某个内存地址的代码:l <*address>
查看汇编代码:info line & disassemble
	查看行/函数的起始终止地址:info line
		查看某行的起始终止地址:info line 
		查看某函数的起始终止地址:info line 
	列出汇编代码:disassemble
		列出当前函数的汇编代码:disassemble 
		列出某个地址段的汇编代码:disassemble  ,  (start_addr和end_addr就是使用info line指令打印出来的起始终止地址)
		列出汇编代码时包含源代码:disassemble /m  , 
  • 停止点管理:break(断点)/watch(观察点)/catch(捕获点)
设定断点:break(b)
	设定文件断点:b 
	设定函数断点:b (注意调试c++程序的时候,必须是file:namespace::classname::func_name)
	设定条件断点:b .... if 
设定观察点:watch/rwatch/awatch (注意只有程序开始运行之后才能设定观察点)
	表达式的值改变时暂停:watch 
	表达式被读取时暂停:rwatch 
	表达式被读取或修改时暂停:awatch 
设定捕获点:catch/tcatch (非HP-UNIX只能用于异常,而编码规范又不让我们用异常...了解就好...)
	设定捕获点:catch ,event可以是下面表中的值(注意,在非HP-UNIX环境下只有throw/catch有用)
		throw	catch exception syscall exec fork vfork load unload 
  tcatch的含义是只捕获一次,并且停住之后自动删除此捕获点
查看停止点:info break / info watch
	查看所有停止点(包括break、watch和catch):info break
	查看某个停止点:info break 
	查看所有观察点:info watch
	查看某个观察点:info watch 
	只能使用info break 查看捕获点(catch point)
disable停止点:disable 
	disable所有停止点:disable
	disable某个停止点:disable 
	disable某个范围内的停止点:disable  (range的例子:1-7)
enable停止点:enable
	enable所有停止点:enable
	enable某个停止点:enable 
	enable某个范围内的停止点:enable  (range的例子:1-7)
删除停止点:delete
	删除全部停止点:delete
	删除某个停止点:delete 
	删除某个范围的停止点:delete  (range的例子:1-7)
清除停止点:clear
	清除当前行停止点:clear
	清除指定行停止点:clear 
	清除指定函数内部所有停止点:clear (注意调试c++程序的时候,必须是file:namespace::classname::func_name)
断点条件修改:condition(只对break有效)
	清除断点条件:condition 
	修改断点条件:condition  
断点命令列表:commands
	设置断点的命令列表:commands 
  	... command list ...
  	end
  • 执行管理
运行程序:run(r)
	开始运行:r
	带命令行参数执行:r 
对正在运行的程序调试:attech & detach
	调试正在运行的程序:attach 
	从正在运行的程序中离开:detach
单步执行进入调用:step(s) 
	单步执行step-in:s
	执行若干步step-in:s 
单步执行跳过调用:next(n) 
	单步执行step-over:n
	执行若干步step-over:n 
继续执行至下一个断点:continue(c)
	继续执行continue:c
	继续执行并忽略指定个数个断点:c 
继续执行跳出当前循环:until(u)
继续执行跳出当前函数:finish(f)
step-mode设定:
	开启step-mode:set step-mode on (让gdb遇到没有debug信息的函数时停止在它的第一行,然后就可以查看它的汇编了)
	关闭step-mode:set step-mode off
单步执行机器码:si(stepi)/ni(nexti) (它们的作用与s和n相同)
强制当前函数返回:return
	当前函数立即返回:return
	当前函数立即以某个返回值返回 :return 
		强制调用函数:call
			强制调用某个函数:call 
			print命令可以达到同样的目的 :print 
		跳转执行:jump(j)
			跳转到某行:j 
			跳转到某文件的某行:j 
			向前向后跳转几行:j +n/-n
			跳转到某个地址:j 
			注意:jump不会修改程序栈中的内容,使用时非常容易引起core,要小心使用
  • 查看信息
打印变量:print(p)
	打印变量:p 
	打印数组中的前n个变量:p @n
	打印其他文件中的变量:p ::
	打印其他函数中的变量:p ::
	格式化打印:p / xxxx
	GDB支持的格式:
		x	十六进制
    d	十进制
		u	无符号十六进制
		o	八进制
		t	二进制
		a	按地址打印(十六进制)
		c	字符
    f	浮点数
显示变量的类型:ptype
	显示变量的类型 :ptype 
查看内存:examine(x)
	打印地址:x 
	打印地址并重复n次:x / 
	按照某种格式打印地址:x / 
 		x	十六进制(默认值)
		i	查看汇编代码
		s	按照字符串格式打印
	按照指定的unit-size打印地址:x / 
 		b	单字节(byte)
		h	双字节
		w	四字节
		g	八字节
		/后面的三个参数可以联合起来使用:x /4bx 
查看栈信息:
	打印栈信息:backtrace(bt)
	打印全部栈信息:bt
	打印当前frame向上n层:bt <+n>
	打印当前frame向下n层:bt <-n>
	切换到栈的某一层:frame(f)
	打印当前栈信息:f
	切换到栈的某一层:f 
	打印当前栈信息:info frame
	沿着栈向上走:up
	沿着栈向下走:down
查看线程信息:
	打印线程信息:info thread
	跳转到某个线程:thread(t)
	打印当前线程信息:t
	切换到某个线程:t 
	设定线程运行模式:set scheduler-locking
	所有线程都可以执行:set scheduler-locking off
	只有当前线程得到执行:set scheduler-locking on
	当前线程最高优先级执行:set scheduler-locking step(也就是说除非当前线程交出运行权限(使用finish/util/continue/next命令),否则其他线程都得不到执行)
查看macro信息:
	查看macro的定义:info macro 
	展开macro:macro expand 
	注意:在编译程序的时候加上gcc的参数-g3
	注意:低版本的gdb/gcc组合可能对macro调试的支持不好,需要4x的gcc和7.4及以上的gdb
查看寄存器信息:
	查看寄存器的值(不包含浮点寄存器):info registers
	查看寄存器的值:info registers
	查看某个寄存器的值:info registers 
	查看所有寄存器的值(包含浮点寄存器):info all-registers
自动显示管理:
	设定自动显示:display 
	打印所有的自动显示:display
	设定自动显示变量:display 
	指定自动显示变量格式:display / 
    x	十六进制
    d	十进制
    u	无符号十六进制
    o	八进制
    t	二进制
    a	按地址打印(十六进制)
    c	字符
    f	浮点数
查看自动显示:info display
	enable自动显示:enable display
	enable所有的自动显示:enable display
	enable某个自动显示:enable display 
	disable自动显示:disable display
	disable所有的自动显示:disable display
	disable某个自动显示:disable display 
	删除自动显示:undisplay / delete display
	删除所有的自动显示:undisplay / delete display
	删除某个自动显示 :undisplay / delete display 
  • 信号处理
查看信号处理策略:info signals / handle
	查看全部信号处理策略:info signals / handle
	查看某个信号处理策略:info signals / handle 
调整信号处理策略:handle
	调整信号处理策略:handle  
	就是info handle/signals中列出的signal名称
	handle支持以下keywords:
		nostop 接收到信号不停止,但是打印信息
		stop	接收到信号停止程序
		print	接收到信号打印信息
		noprint	接收到信号不打印信息
		pass	GDB不响应这个信号
		noignore	GDB不响应这个信号
		nopass	GDB响应这个信号
		ignore	GDB响应这个信号
产生信号量:signal
	产生某个信号:signal 
  • 其他
命令行参数操作:set  args & show args
	设定命令行参数:set args 
	显示命令行参数:show args
运行时动态修改内存中变量的值:set var
	使用print命令:print =
	使用set var命令:set var =
一些有用的显示设定:
	美化数组打印:set print array on
	美化结构体打印:set print pretty on
	打印union中的数据:set print union on
	基于虚函数表打印:set print object on

实用技巧

  • 调试core
1.使用gdb  打开core文件
2.之后bt打印栈信息,找到需要查看的位置
3.f 到该位置
4.使用l显示附近的代码,使用p打印需要查看的变量
  • 调试正在运行中的程序
1.ps aux|grep xxx查找对应程序的pid
2.gdb -p pid或者启动gdb之后attach pid
3.使用info thread查看线程信息,使用t 跳到需要查看的线程
4.之后bt打印栈信息,找到需要查看的位置
5.f 到该位置
6.使用l显示附近的代码,使用p打印需要查看的变量
7.也可以用b设定断点之后再c,等等
8.注意:退出时需要先detach再quit,否则会终止该程序
  • 打印stl库中的变量内容
1.gdb中对stl类型变量的打印支持的不好,所以需要使用内存地址来打印对应的信息
2.首先p ,打印这个对象的内容,比如说一个vector对象
3.然后根据具体打印的信息,找到对应的内存地址
4.根据这个内存地址信息,就可以打印对应的内容了
  • gdbinit文件与gdb脚本
gdb与vim相似,启动时加载$home目录下的.gdbinit文件,一些显示设定可以直接写在.gdbinit文件中来始终生效
gdb与vim相似,支持用户编写自己的脚本,例如:打印stl容器的gdb脚本,http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表