启动GDB的方法有以下几种:
1、gdb <program>
program也就是你的执行文件,一般在当然目录下。’
例如我写了一个简单的helloword程序
#include <stdio.h>
int main(){
int a = 1;
char* ch = "hello world";
printf("%s\n",ch);
return 0;
}
那么我编译的时候使用-g参数。gcc -g -o t t.c
2、gdb <program> core
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
这里不得不说下ulimit参数(耐心等候,我在C语言的调试教程完结后会给大家分享ulimit的内容)
3、gdb <program> <PID>
如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。
例如我写了一个很二逼的代码,让他后台执行helloworld的打印输出
#include <stdio.h>
#include <stdlib.h>
int main(){
int a = 1;
while(1){
char* ch = "hello world";
printf("%s\n",ch);
sleep(2);
}
return 0;
}
gcc -g -o t t.c
我启动的时候通过 nohup ./t &后台执行,也可以在另外一个终端里./t执行。
然后ps -ef|grep t 正则找出我准备要调试的进程
然后先gdb进入
这样,我就可以查看当前进程的信息调试。
4、在gdb中,运行程序使用r或是run命令。
程序的运行,你有可能需要设置下面四方面的事。
1、程序运行参数。
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。
2、运行环境。
path <dir> 可设定程序的运行路径。
show paths 查看程序的运行路径。
set environment varname [=value] 设置环境变量。如:set env USER=edward
show environment [varname] 查看环境变量。
3、工作目录。
cd <dir> 相当于shell的cd命令。
pwd 显示当前的所在目录。
4、程序的输入输出。
info terminal 显示你程序用到的终端的模式。
使用重定向控制程序输出。如:run > outfile
tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb
5、过程控制
(1)设置断点(BreakPoint)
我们用break命令来设置断点,当然你可以使用缩写b,有几种设置断点的方法:
break <function> 或者 b function
在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。
break <linenum>
在指定行号停住。
break +offset
break -offset
在当前行号的前面或后面的offset行停住。offiset为自然数。
break filename:linenum
在源文件filename的linenum行处停住。
break filename:function
在源文件filename的function函数的入口处停住。
break *address
在程序运行的内存地址处停住。
break
break命令没有参数时,表示在下一条指令处停住。
break ... if <condition>
可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。
查看断点时,可使用info命令,如下所示:(注:n表示断点号)
info breakpoints [n]
info break [n]
这块你我只举1例:
仍然是刚才的代码,我在代码的第8行打了断点,那么在我执行c(continue)的时候程序将继续执行,直到执行到断点处:
(2)设置观察点(WatchPoint)
观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
watch <expr>
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
rwatch <expr>
当表达式(变量)expr被读时,停住程序。
awatch <expr>
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前所设置了的所有观察点。
(3)设置捕捉点(CatchPoint)
你可设置捕捉点来捕捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
catch <event>
当event发生时,停住程序。event可以是下面的内容:
1、throw 一个C++抛出的异常。(throw为关键字)
2、catch 一个C++捕捉到的异常。(catch为关键字)
3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
6、load 或 load <libname> 载入共享库(动态链接库)时。(load为关键字,目前只在HP-UX下有用)
7、unload 或unload <libname>卸载共享库(动态链接库)时。(unload为关键字,只在HP-UX下有用)
tcatch <event>
只设置一次捕捉点,当程序停住以后,应点被自动删除。
6. 查看运行时的堆栈:
使用bt命令,如我在最开始使用的bt
如果我希望进入到main函数里,那么我执行 f 2 就进入到main函数里,如果我执行f 1就进入到了 sleep函数栈里。
7. 打印某个变量的值:
print val
如果你希望一直显示某一变量,那么你可以使用dispalay val 或者disp val.
8. 单步: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
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。