对于一般的设断点、单步运行、查看变量的值和函数调用堆栈等调试使用eclipse就够了。但是有时候想输出大量的调试信息,并对程序做很多跟踪控制,这时候用命令行可能会比IDE更方便一点。而且eclipse是基于GDB的,所以熟悉GDB的使用对eclipse里调试环境的配置也会有一定帮助。
一、 基本命令
这里不打算介绍很多命令,只是介绍一些基本的命令来对GDB有一个基本的认识。
对于GDB命令,为了方便调试,通常可以用该命令的第1个字母来代替整条命令,如用b代替break、用r代替run等。
进入调试程序所在目录,通过gdb [程序名]命令来启动gdb调试,也可以不带程序参数,在进入GDB后通过file [程序名]来指定要调试的程序,进而加载符号表。
break:用来设断点,如在test.c的第10行设断点 break test.c:10
run:程序第一次运行
continue:断点后继续运行,后面跟数字表示重复次数,如continue 10表示重复10次
list:查看代码
next:单步调试,不进入函数里面
step:单步调试,进到函数里面
info local:显示所有局部变量的值,有时碰到gdb调试无法查看变量值,这是因为编译器开了优化,没有把变量导出到符号表,编译时加上-gstabs+就可以了。
print:后面加变量名,显示变量的值
backtrace(bt):查看函数调用堆栈
command:在输入该命令后会让你再输入其他命令以end结束,表示断点之后继续执行的命令
set args:设置程序输入参数
quit:结束调试
二、 文件的导入和导出
这应该是GDB直接调试相对eclipse的最大优势了吧,可以先把一系列调试命令写好保存在文件里,还可以在文件里写一些脚本,然后从文件导入执行调试。
调试信息还可以导出到文件,方便查看分析。
一般可以在启动GDB时指定要导入的文件,命令如下:
gdb –command= 文件名
导出文件命令如下:
set logging file 文件名
set logging on
这时所有GDB的信息都会输出到指定的文件,如果要停止输出到文件,使用如下命令
set logging off
也可在启动时直接把整个gdb会话期间的信息都重定向到文件:
gdb |tee 文件名
三、 tracepoint的使用
想要详细了解tracepoint的使用可以参考以下2个网址的介绍:
Linux Kernel GDB tracepoint module(KGTP):
http://teawater.github.io/kgtp/kgtpcn.html
Debuggingwith GDB: Tracepoints:
https://sourceware.org/gdb/onlinedocs/gdb/Tracepoints.html
接下来主要参照一个网友写的demo来实践一下tracepoint的基本使用,原文地址为
http://blog.youkuaiyun.com/Morphad/article/details/17310167
有时候我们调试的时候不希望设断点让程序停下来,如通信、linux内核调试等,因为如果停下来就改变了程序的运行状态,就得不到正确的调试信息。
如果是本地调试的话,我们可以通过printf来把要查看的变量打印出来,如果是远程调试的话不好修改程序,这时候tracepoint就派上了用场。
在tracepoint.c里输入如下例子程序
#include <stdio.h>
#include <unistd.h>
int indx;
int tracepoint(void)
{
int res;
indx = 0;
while ( indx < 10000 ) {
res = indx * 2;
printf("%d\n", res);
sleep(1);
indx++;
}
return 0;
}
int main(int argc, char *argv[])
{
tracepoint();
return 0;
}
这里特意新建一个函数,因为用gdb调试时main的局部变量是看不到。
然后编译,别忘了加-gstabs+
gcc -g -gstabs+ tracepoint.c -o tracepoint
编译好后运行
./ tracepoint
再按ctrl+z挂起程序
用pidof tracepoint查看进程号,如果有多个选第1个。
然后启动gdbserver监听端口号,让tracepoint处于远程调试状态,这里设置127.0.0.1的本地回射ip:
gdbserver --attach 127.0.0.1:1234 `pidof tracepoint`
然后新建一个command文件,输入以下内容
file tracepoint
target remote 127.0.0.1:1234
trace tracepoint.c:15
actions
collect indx
end
tstart
break tracepoint.c:14
continue
continue 2
tstop
tstatus
tfind
while($trace_frame != -1)
printf "Frame %d : indx = %d\n", $trace_frame, indx
tfind
end
这里action表示在遇到trace断点后要做的事情,以end结束,这里是记录indx变量的值,trace以tstart开始,以tstop结束。tfind用来显示之前记录下的信息。
再新建一个终端,用gdb运行该command文件:
gdb -command=command
在tracepoint里记录局部变量的值是看不到的,不知道为什么,但是普通断点调试还是可以看到的。