百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

linux下GDB使用方法(linux怎么用gdb调试)

yuyutoo 2025-05-09 22:38 5 浏览 0 评论

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

一般来说,GDB主要帮助你完成下面四个方面的功能:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。


一、普通命令

(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h

(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r

(gdb)start:单步执行,运行程序,停在第一执行语句。

(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l

(gdb)set:设置变量的值

(gdb)next:单步调试(逐过程,函数直接执行),简写n

(gdb)step:单步调试(逐语句:跳入自定义函数内部执行),简写s

(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt

(gdb)bt full:不仅显示backtrace,还显示局部变量。

(gdb)frame:切换函数的栈帧,简写f

(gdb)info:查看函数内部局部变量的数值,简写i

(gdb)finish:结束当前函数,返回到函数调用点

(gdb)continue:继续运行,简写c

(gdb)print:打印值及地址,简写p

(gdb)p *array@len :显示数组, p相当于print,array就是数组首地址,也可以是数组名,len是想要显示的数组的长度。

(gdb)quit:退出gdb,简写q

(gdb)break+num:在第num行设置断点,简写b

(gdb) break 9 if sum != 0 :满足条件才激活断点

(gdb)info breakpoints:查看当前设置的所有断点

(gdb)delete breakpoints num:删除第num个断点,简写d

(gdb)display:追踪查看具体变量值

(gdb)undisplay:取消追踪观察变量

(gdb)watch:被设置观察点的变量发生修改时,打印显示。比如:watch input[4]

(gdb)i watch:显示观察点

(gdb)enable breakpoints:启用断点

(gdb)disable breakpoints:禁用断点

(gdb) x/<n/f/u> <addr>:查看内存, n、f、u是可选的参数。 <addr>表示一个内存地址。(比如: x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示输出三个单位,u表示按十六进制显示。)

(gdb)run argv[1] argv[2]:调试时命令行传参。


二、高级命令

1、调试设置参数的方法,有两种:

1)run 参数1 参数2 参数n

2)set args 参数1 参数2 参数n

可用 show args 查看。


2、gdb调试已在运行的进程

gdb -p <进程号>

或者:

gdb attach <进程号>


1.1)通过命令:ps -aux | grep 进程名(比如:main) ,获取执行main的进程(pid),比如获取到pid:10001

1.2)启动gdb attach,执行gdb attach pid即可调试正在运行的程序,输入命令:gdb attach 10001

若执行gdb attach时提示:” ptrace: Operation not permitted”,说明权限不够,切换root用户运行,执行:sudo gdb attach 10001

1.3)设置源码映射,对源码路径重新设置。[可选]

set substitute-path /home/johnchen1/workspace/OldCode /home/johnchen2/other/NewCode

源码路径:
/home/johnchen1/workspace/OldCode

实际代码路径:
/home/johnchen2/other/NewCode

用实际代码替换源码,此过程需要包版本和代码版本一致。

1.4)设置断点

b xxx.cpp:100

//调试xxx.cpp文件,断点为100行。

1.5)已是运行中的程序不需要启动(r),继续(c)即可。

1.6)等待指令或报文触发断点,被击中会停留在断点行。

1.7)其他gdb操作(s单步调试(逐语句:跳入自定义函数内部执行);n单步调试(逐过程,函数直接执行);bt等)


3、使用GDB时对源码路径重新设置

有的时候一个程序不是在同一个机器上执行的,当调试的时候就可能无法找到源代码的路径,这时就需要使用下面的方法了:

当gdb程序找不到源码时,进行重新设置源码路径步骤:

(1). 使用如下命令查看目标文件中保存的是相对路径还是绝对路径

readelf -p .debug_str target_bin_file

(2). 如果是相对路径:

使用 gdb 的dir命令添加的源码搜索路径

(3). 如果是绝对路径:

进行路径重新映射:set substitute-path old_path new_path

查看当前环境设置的调试目录:show directories


4、examine

examine(x)可以按照一定的格式打印内存地址处的数据,详细文档可参考这里。

(gdb) x/{COUNT}{FMT}{SIZE} {ADDRESS}

{COUNT}: 打印的数目,默认为1。

{FMT}: 打印的格式1,默认为上次使用的{FMT}:

o(octal): 8进制整数

x(hex): 16进制整数

d(decimal): 10进制整数

u(unsigned decimal): 10进制非负整数

t(binary): 2进制整数

f(float): 浮点数

a(address): 输出相对于前面最近的符号的偏移

i(instruction): 输出地址处的汇编指令

c(char): 字符

s(string): c字符串(null-terminated string)

z(hex, zero padded on the left): 见说明

{SIZE}: 打印的字节数目,默认为上次使用的{SIZE}:

b(byte): 1个字节

h(halfword): 2个字节

w(word): 4个字节

g(giant, 8 bytes): 8个字节

{ADDRESS}: 目标地址


举个例子:

(gdb) x/a 0x401419

0x401419 <main()+113>: 0x55c3c900000000b8


(gdb) x/i 0x40138d

=> 0x40138d <crash(int, double)+41>: mov -0x10(%rbp),%eax


(gdb) x/1fg 140737488346064

0x7fffffffdbd0: 10.125


5、GDB堆栈跟踪

程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都被分配了一个“帧”,

最近调用的函数在 0 号帧中(“底部”帧)。要打印堆栈,发出命令 'bt'('backtrace' [回溯] 的缩写):

(gdb) bt

#0 0x80483ea in wib (no1=8, no2=8) at eg1.c:7

#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

此结果显示了在 main() 的第 21 行中调用了函数 wib()(只要使用 'list 21' 就能证实这一点),而且 wib() 在 0 号帧中,

main() 在 1 号帧中。由于 wib() 在 0 号帧中,那么它就是执行程序时发生算术错误的函数。

实际上,发出 'info locals' 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。

可以使用命令 'frame' 打印当前帧。要查看 main 函数(在 1 号帧中)中的变量,可以发出 'frame 1' 切换到 1 号帧,

然后发出 'info locals' 命令:

(gdb) frame 1

#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

21 result = wib(value, div);

(gdb) info locals

value = 8

div = 8

result = 4

i = 2

total = 6

此信息显示了在第三次执行 "for" 循环时(i 等于 2)发生了错误,此时 "value" 等于 "div"。

可以通过如上所示在 'frame' 命令中明确指定号码,或者使用 'up' 命令在堆栈中上移以及 'down' 命令在堆栈中下移来切换帧。

要获取有关帧的进一步信息,如它的地址和程序语言,可以使用命令 'info frame'。


6、线程相关的命令

一些调试多线程程序时常用的命令:

info threads: 查看线程列表

thread 2: 切换到2号线程,线程编号可由info threads得知

thread apply all bt: 打印所有线程的堆栈


7、使用linux的GDB打印STL(vector,map,set等)

https://www.cnblogs.com/silentNight/p/5466418.html

相关推荐

MATLAB实例讲解—求二元函数的极值

实例程序...

解析式大赛的获奖作品代码和公式公布啦!

上方超级数学建模可加关注传播数学干货,学会理性的方式去思考问题大家期待已久的运行代码终于新鲜出炉了!!!抱歉让各位粉丝久等了接下来就是揭秘奇迹的时刻1、emoji解析式:无代码:holdon...

基于MATLAB的ACC控制算法设计及仿真测试

作者...

MATLAB基础学习之坐标转换(matlab改坐标)

(一)平面坐标转换1.cart2pol:将笛卡尔坐标转换为极坐标;2.pol2cart:将极坐标转换为笛卡尔坐标;(二)立体坐标转换1.cart2sph:将笛卡尔坐标转换为极坐标;2.sph2cart...

Java NIO:从 Buffer、Channel、Selector 到 Zero-copy、I/O 多路复用

NIO...

「太极创客」零基础入门学用物联网 - MQTT篇 1-9 自我测试

到目前为止,我们已经掌握了MQTT通讯的基本流程以及如何使用ESP8266来发布和订阅MQTT消息。这节课我们来进行自我测试。...

用豆包改了一下午程序,感觉它聪明得超乎想象

之前低估了AI的聪明程度,AI持续学习下去,未来可以做的事情太多了,编程已经算是比较复杂的事情都能完成得这么好,那些项目计划、工作报告更是小儿科。今天用豆包改了几个程序,提出的BUG也能修改完成...

Node-Media-Server开源流行Nodejs流媒体服务器

简介Node-Media-Server一个Node.js实现的RTMP/HTTP/WebSocket/HLS/DASH流媒体服务器。开源github地址:https://github.com/il...

如何应对 RAG 开发挑战?12 个痛点逐一击破

受到论文《SevenFailurePointsWhenEngineeringaRetrievalAugmentedGenerationSystem》的启发,并结合实际开发RAG(检...

团队协作-代码格式化工具clang-format

环境:clang-format:10.0.0前言统一的代码规范对于整个团队来说十分重要,通过git/svn在提交前进行统一的ClangFormat格式化,可以有效避免由于人工操作带来的代码格式问题。C...

如何编写自己的Arduino库?(arduino怎么自己写库)

支持一对一答疑的购买地址...

Auto CAD 命令(A)(cad命令aaw)

ABOUT(命令)显示有关产品的信息。...

一文读懂设计模式,看这篇就够了(设计模式是干嘛的)

转载:javadoop.com/post/design-pattern一直想写一篇介绍设计模式的文章,让读者可以很快看完,而且一看就懂,看懂就会用,同时不会将各个模式搞混。自认为本文还是写得不错的,花...

ASL开发者指南:构建健壮高效的C++应用

1.库介绍AdobeSourceLibraries(ASL),现在由stlab维护,是一组专注于提供高质量、经过实战检验的C++组件的集合。它最初由Adobe公司开发,旨在解决构建...

linux下GDB使用方法(linux怎么用gdb调试)

gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。一般来说,GDB主要帮助你完成下面四个方面的功能:1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。2、可让被调试的程...

取消回复欢迎 发表评论: