linux下gdb调试方法和技巧详解

本文详细介绍了Linux下GDB的使用方法和技巧,包括启动、查看源码、设置断点、单步执行、查看变量等基本操作,以及如何进行多线程调试、反向调试等高级技巧。通过学习,读者将能熟练掌握GDB的调试技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linuxgdb调试方法和技巧整理

简介

UNIX或者UNIX-like下调试工具

启动gdb
# 1. 在可执行程序不需要输入参数时,我们可以使用 gdb + 可执行程序 
 gdb  ./typeid_test 
 # 2. 可执行程序需要输入参数时, 我们使用 gdb --args + 可执行程序 + args
 gdb --args ./MPEG2TransportStreamIndexer1 /work/video/sky.ts
 # 3. 连接已经运行的程序
 gdb -p + pid
 # 4. 可执行程序带参数  (一)gdb + 可执行程序名 (二)然后再使用set args + 参数
 gdb + 可执行程序名
查看源码
# list 简称l, 默认向下,如果想向上需要指定对应负数行数  l -3
list 
运行程序
# 使用run 命令运行程序,简称r
run
设置断点
# 1. b +  func
b main
# 2. b + file:line
b main.cpp:36
查看断点
# info b
删除断点
# 1. 删除指定的断点
delete 3
# 2. 删除所有断点
delete 回车,之后输入y确认删除所有断点
单步执行
# 1. 如果遇到函数不进入到函数里面  next(n) / ni
# 2. 如果遇到函数调用,进入到函数里面, step(s) / si
查看变量
(gdb) p fileName=0x7fffffffe0f6
$1 = 0x7fffffffe0f6 "/work/video/sky.ts"
退出
quit

正常调试

  1. 取指定位置的堆栈操作
(gdb) x /200aw $sp
  1. 单步执行step(进入函数内,源码层面)/stepi(机器指令层面)
(gdb) s
  1. 单步执行(不进入函数内)
(gdb) n
  1. 设置动态库相对搜索路径
(gdb) set solib-search-path + path
  1. 设置动态库绝对搜索路径
(gdb) set solib-absolute-prefix + path

6.继续执行到下一个断点(恢复所有线程的执行)

(gdb) c
  1. 选择进入对应的栈
f + num
  1. 连接上对应的进程
gdb -p pid
  1. 查看所有线程的堆栈
thread apply all bt
  1. 多线程调试,启停其他线程
set scheduler-locking [ off| on | step]
#off 不锁定任何线程, on表示只有当前被调试的线程继续执行, step 表示单步执行的时候,只有当前线程执行
  1. 设置命令行参数
set args 命令号参数
  1. 按照字符的形式打印sp附近的指定字节
x /200aw $sp
  1. gdb调试守护进程,设置了如下两个参数之后在gdb环境下可以在父进程退出之后跟随子进程
set follow-fork-mode child
set unwindonsignal on

follow-fork-mode有两个参数可以使用,parent 是在调用fork之后继续跟踪父进程,child是在执行fork之后继续跟踪子进程

Set debugger response to a program call of fork or vfork.

A fork or vfork creates a new process. follow-fork-mode can be:

parent - the original process is debugged after a fork

child - the new process is debugged after a fork

The unfollowed process will continue to run.

By default, the debugger will follow the parent process.

unwindonsignalgdb调用函数的时候,接收到信号的处理方式

Set unwinding of stack if a signal is received while in a call dummy.

The unwindonsignal lets the user determine what gdb should do if a signal

is received while in a function called from gdb (call dummy). If set, gdb

unwinds the stack and restore the context to what as it was before the call.

The default is to stop in the frame where the signal was received.

  1. thread命令
thread name   [name]#为当前线程设置命名
thread applay [command] # 为当前线程应用对应的命令
thread find # 查找符合描述的线程,查找条件一般按照线程命名查找,Will display thread ids whose name, target ID, or extra info matches REGEXP
  1. 查看本地变量命令
i locals 
  1. 使用watch监控变量
watch variable if variable == 66
  1. 运行完一个函数,跳到函数调用的地方finish

该命令还可以用于跳出循环使用

finish
  1. 跳出函数,指定函数返回值return
return 119
  1. 跳出循环finish 或者until
finish # 跳出当前循环(跳出当前栈)
util num # 运行到指定行结束运行
  1. 打印指向子类对象的父类指针

打印父类指针的时候经常使用p *lpWidget,因为父类指针只能按照父类的信息提取对象的内容,父类一般都是虚基类,因此打印出来的信息可能就一张虚函数表。这个时候要想打印全部的信息,需要在代码中找到子类的定义,在打印信息中将指针强制转换成子类类型指针之后再进行取值打印,一般一般如下:

p *(Derive *)lpWidget

反向调试

GDb7.0以上的平台开始支持反向调试

反向调试需要开启记录,调试结束关闭记录,只有在开启记录之后才能完全正常的进行反向调试。

  1. 开启记录关闭记录
# 开启记录
record
# 关闭记录
record stop
  1. 向上走一步reverse-step/reverse-stepi进入函数内部
reverse-step/reverse-stepi
  1. 向上走一步源码层面reverse-next/reverse-nexti
reverse-next/reverse-nexti
  1. 反向运行到调用当前函数的地方
reverse-finish
  1. 设置程序运行方向,能够像正常调试方式一样反向调试
set exec-direction [forward | reverse]

在这里插入图片描述

飞书文档
公众号文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achilles.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值