类UNIX下C/C++开发,代码调试比较麻烦,最原始的加跟踪调试很土,也很费时,特别是一个庞大的项目,代码行数非常大的时候调试起来非常费劲,当core dump时定位也不容易,这里介绍几个常用工具: gdb、dbx调试工具,valgrind内存检查工具(Linux) 。
gdb(GNU DeBugger)是GNU的调试器,一般和gcc配搭使用。要使用GDB进行调试,编译程序时要指定-g或-ggdb的编译选项。如: gcc –g main.c
gdb指令:f(file):指定可执行文件,l(list)列出源文件,r(run)运行可执行文件,可带执行参数,b(break)设置断点,c(continue)继续被中断程序执行,直到下一个断点或者程序结束,p(print)输出变量的值,如p aa;n(next)单步执行,s(step)程序执行到断点时中断执行,可以用s指令进行单步执行进入某一函数。q(quit)退出。
当在gdb运行时想运行shell命令,不必退出,执行shell切换到shell模式,执行shell命令。
GDB有能力在你调试程序的时候处理任何一种信号,你可以告诉GDB需要处理哪一种信号。你可以要求GDB收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试。你可以用GDB的handle命令来完成这一功能。handle <signal> <keywords...>
在GDB中定义一个信号处理。信号<signal>可以以SIG开头或不以SIG开头,可以用定义一个要处理信号的范围(如:SIGIO-SIGKILL,表示处理从SIGIO信号到SIGKILL的信号,其中包括SIGIO,SIGIOT,SIGKILL三个信号),也可以使用关键字all来标明要处理所有的信号。一旦被调试的程序接收到信号,运行程序马上会被GDB停住,以供调试。其<keywords>可以是以下几种关键字的一个或多个。 nostop 不停止运行,只输出显示信号,stop:停住程序,print显示一条信息,noprint当被调试的程序收到信号时,GDB不会告诉你收到信号的信息,noignore当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序会处理。nopass,ignore当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。
查看core文件:运行gdb 执行文件 core文件 来加载core文件,使用where来查看coredump位置。如果系统未产生core文件,可使用ulimit -c 2048命令,后运行执行文件产生。
多进程调试:在我们的测试程序在父进程fork后,子进程调用sleep睡了60秒。这就是关键,这个sleep本来是不该存在于子进程代码中的,而是为了使用GDB调试后加入的,为什么要让子进程刚刚运行就开始sleep呢?因为我们要在子进程睡眠期间,利用shell命令获取其process id,然后再利用gdb调试外部进程的方法attach到该process id上,调试该进程。
动态库调试,运行执行程序加载动态库来调试。
下一篇:dbx工具介绍