gdb查看源码
⑴ 如何使用gdb调试可执行程序与源程序
简单来说,有两种方式,一种是源码debug,即分析源码来找出bug位置,一般使用printf()打印出程序执行每一步的信息,一种是可执行文件debug
⑵ gdb在调试时是如何找到源文件在哪里
默认会对两个路径进行搜索:
编译的时候的源文件路径
当前gdb的路径(即在gdb种执行pwd显示的路径,可以用cd改变)
所以你知道为什么不管可执行文件放到哪里,都能找到源文件了吧~如果你把源文件移走,就找不到了。这个时候,你可以通过dir命令添加路径进行查找。
⑶ 如何用 Gdb debug /system/bin/linker
1: 对于在应用程序中加入参数进行调试的方法:
直接用 gdb app -p1 -p2 这样进行调试是不行的。
需要像以下这样使用:
#gdb app
(gdb) r -p1 -p2
或者在运行run命令前使用set args命令:
(gdb) set args p1 p2
可以用show args 命令来查看
2. 加入断点:
break <linenumber>
break <funcName>
break +offset
break -offset
(在当前行号的前面或后面的offset行停住。)
break filename:linenum
在源文件filename的linenum行处停住。
break filename:function
在源文件filename的function函数的入口处停住。
break ... if
...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置 break if i=100,表示当i为100时停住程序。
3. 查看运行时的堆栈:
使用bt命令
4. 打印某个变量的值:
print val
5. 单步: n
继续运行:c
step
单步跟踪,如果有函数调用,他会进入该函数。
next
同样单步跟踪,如果有函数调用,他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一条条地执行,加表示执行后面的count条指令,然后再停住。
set step-mode
set step-mode on
打开step-mode模式,于是,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。
set step-mod off
关闭step-mode模式。
finish
运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。
until 或 u
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
6.在GDB中执行shell命令:
在gdb环境中,你可以执行UNIX的shell的命令,使用gdb的shell命令来完成:
eg. shell make
7. 运行环境
可设定程序的运行路径。
show paths 查看程序的运行路径。
set environment varname [=value] 设置环境变量。如:set env USER=hchen
show environment [varname] 查看环境变量。
8.观察点(WatchPoint)
观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程 序。我们有下面的几种方法来设置观察点:
watch
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
rwatch
当表达式(变量)expr被读时,停住程序。
awatch
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前所设置了的所有观察点。
9. 维护breakpoint
clear
清除所有的已定义的停止点。
clear func
清除所有设置在函数上的停止点。
delete [breakpoints] [range...]
删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。
比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。
disable [breakpoints] [range...]
disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止 点。简写命令是dis.
enable [breakpoints] [range...]
enable所指定的停止点,breakpoints为停止点号。
10、程序变量
查看文件中某变量的值:
file::variable
function::variable
可以通过这种形式指定你所想查看的变量,是哪个文件中的或是哪个函数中的。例如,查看文件f2.c中的全局变量x的值:
gdb) p 'f2.c'::x
查看数组的值
有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:
int *array = (int *) malloc (len * sizeof (int));
于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:
p *array@len
如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。
11.输出格式
一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
(gdb) p i
$21 = 101
(gdb) p/a i
$22 = 0x65
(gdb) p/c i
$23 = 101 'e'
(gdb) p/f i
$24 = 1.41531145e-43
(gdb) p/x i
$25 = 0x65
(gdb) p/t i
$26 = 1100101
11.查看内存
使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:
x/
n、f、u是可选的参数。
n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。
f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
n/f/u三个参数可以一起使用。例如:
命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。
12.自动显示
你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的GDB命令是display。
display
display/
display/ expr
expr是一个表达式,fmt表示显示的格式,addr表示内存地址,当你用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。
格式i和s同样被display支持,一个非常有用的命令是:
display/i $pc
undisplay
delete display
删除自动显示,dnums意为所设置好了的自动显式的编号。
disable display
enable display
disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。
info display
查看display设置的自动显示的信息。GDB会打出一张表格,向你报告当然调试中设置了多少个自动显示设置,其中包括,设置的编号,表达式,是否enable。
13. 设置显示选项
set print address
set print address on
打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的,
show print address
查看当前地址显示选项是否打开。
set print array
set print array on
打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的。与之相关的两个命令如下,我就不再多说了。
set print array off
show print array
set print elements
这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。
show print elements
查看print elements的选项信息。
set print null-stop
如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。
set print pretty on
如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。
14.关于显示源码list
⑷ gdb调试命令是什么
gdb调试命令如下:
1、启动gdb
$gdb
这样可以和gdb进行交互了。
2、启动gdb,并且分屏显示源代码
$gdb -tui
这样,使用了'-tui'选项,启动可以直接将屏幕分成两个部分,上面显示源代码,比用list方便多了。这时候使用上下方向键可以查看源代码,想要命令行使用上下键就用[Ctrl]n和[Ctrl]p。
3、启动gdb调试指定程序app
$gdb app
这样就在启动gdb之后直接载入了app可执行程序,需要注意的是,载入的app程序必须在编译的时候有gdb调试选项,例如'gcc -g app app.c',注意,如果修改了程序的源代码,但是没有编译,那么在gdb中显示的会是改动后的源代码,但是运行的是改动前的程序,这样会导致跟踪错乱的。
4、启动程序之后,再用gdb调试
$gdb <program> <PID>
这里,<program>是程序的可执行文件名,<PID>是要调试程序的PID.如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。
5、启动程序之后,再启动gdb调试
$gdb <PID>
这里,程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID,<PID>是要调试程序的PID.这样gdb就附加到程序上了,但是现在还没法查看源代码,用file命令指明可执行文件就可以显示源代码了。
⑸ 怎样调试GCC源码
一、linux程序gcc编译步骤:
Gcc编译过程主要的4个阶段:
l 预处理阶段,完成宏定义和include文件展开等工作;(.i)
l 根据编译参数进行不同程度的优化,编译成汇编代码(.s.S)
l 用汇编器把汇编代码进一步生成目标代码(.o)
l 用连接器把生成的目标代码和系统或用户提供的库连接起来,生成可执行文件
格式:
l gcc -E test.c//预处理阶段
l Gcc -S test.c//编译阶段
l Gcc -c test.c//汇编阶段
l Gcc -o test test.c//链接阶段
二、Linux程序gdb调试步骤:
Gdb的功能:
l 设置断点
l 监视程序变量的值
l 程序的单步执行
l 显示、修改变量的值
l 显示、修改寄存器
l 查看程序的堆栈情况
l 远程调试
Gdb调试过程:
1、程序经过预处理后,即进入编译阶段,进入编译阶段,首先声明编译:
2、格式:gdb -o test test.c -g
3、进入编译:gdb test
4、显示需要编译调试的源程序:l(list)//list filename
5、设置断点:b(break)行号
6、查看设置的断点:info b
7、运行调试程序:run
8、跳到下一个断点:c(continue)
9、单步运行的话使用:n(next)/s(step into)跳到函数体 //区别在与:next执行函数体,而step不执行函数体
10、调试过程中查看某个变量的变化:print i (每次都要手动设置)//display i(设置一次一直尾随,直到用“undisplay 变量标号” 停止)
11、退出当前的调试使用finish 跳出函数
12、清楚断点 clear 行号
13、Delete 断点信息序号// 删除所有断点或设置的要删除的断点
14、退出调试 q
15、b num if i==20 设置断点的触发条件
16、condition num i==50 改变断点的触发条件
⑹ 如何使用gdb调试,类似于vc那样的带源码窗口
很简单,只需要带参数:-tui启动即可,看到界面:
但是默认焦点是在上面源代码窗口上的(使用↑,↓、PgDn、PgUp键对源代码窗口有效),可使用命令“info win”看看焦点的位置:
(gdb) info win
SRC (15 lines) <has focus>
CMD (8 lines)
(gdb)
想要切换到命令窗口:fs CMD;
想要切换到源码窗口:fs SRC
注意:大小写敏感。直接:
(gdb) fs
warning: Incorrect Number of Arguments.
Usage: focus {<win> | next | prev}
=====================================================================
配合窗口经常使用的命令:
where——程序运行到了何处;
list——列出程序运行处附近10行源码;
⑺ gdb加载动态库成功,但是不能显示动态库中的源码(gdb+gdbserver)
因为具体的给的不够详细,不清楚你遇到的情况。
如果仅从断点上看,应该就是CApartment.cpp:55
但是,如果你的程序编译的时候,不是-O0,那个可能回不到源码,只能看汇编。
1、有时候(很少)就是编译器的错误。
2、还有可能就是你调试的程序和你的源码不匹配
3、你的程序已经崩溃了,破坏了堆栈或者GDB需要的数据。
4、这个地方有特殊的定位信息
5、其他情况,还是比较多的,经常遇到。
如果懂汇编,最好看看汇编。
如果不懂,看看那一条语句是最后一条能够跟踪的语句。
仔细看看最后一条语句的所有变量,应该能猜出来是什么问题。
⑻ 求助,我在linux下安装的Qt5为什么用GDB调试器无法进入源码
打开命令终端面板输入:sudo apt-get install gdb 如图所示: 即可安装,如果还是不可以,那就使用下面这种方式安装: 打开终端输入: wget ftp://ftp.gnu.org/gnu/gdb/gdb-7.9.tar.gz 下载完毕后解压 tar -zxvf /gdb-7.9.tar.gz 然后进行安装即可
⑼ GDB调试无法加载源码
你使用Makefile编译调试的吧。
注意Makefile的写法,一个空格也会造成错误的。
在编译的代码中添加 -g 和 -Wall 。-g是为了GDB调试用的,-Wall可以显示全部的警告,对你分析程序很有好处。
这个Segemental fault 是段错误,造成这个错误的原因有很多,可能是内存 或者 栈溢出,出现这个错误需要功过GDB反复调试,查看错误原因。