gdb、arm-linux-gdb以及gdbserver的安装过程在此略去,这里主要简要记录开发过程中的主要流程和使用的主要命令。
1、PC调试
PC调试,就是调试PC上的程序。
1.1 编译程序
使用gcc编译程序,为了使用gdb进行调试,加上选项-g:
$ gcc test.c -g # 加上-g选项
1.2 加载程序
先启动gdb工具,然后使用file命令加载需要调试的程序:
$ gdb # 启动gdb工具 $ file a.out # 加载程序a.out1.3 运行程序
加载程序后,可以使用r命令运行:
$ r # run
1.4 设置/删除/查看断点
$ b func1 # 在函数func1处设置断点 $ b 18 # 在第18行处设置断点 $ d 2 # 删除编号为2的断点 $ d # 删除所有断点 $ clear # 清除所有断点 $ clear 18 # 清除第18行处的断点 $ clear func1 # 清除函数func1处的断点 $ info b # 查看当前设置的所有断点
1.5 继续运行
设置断点后,可以使用c命令继续从断点处开始执行程序(使用r命令会使得程序重新运行)
$ c # continue1.6 单步运行
可以使用s命令进行单步调试(step in,会跳进调用的函数里面!)
$ s # step, (step in) $ n # next, (step over)
1.7 查看变量
$ p tmp # print 变量tmp的值
1.8 退出
$ quit # 退出gdb
2、交叉调试
交叉调试,就是通过PC来调试开发板上的程序。
2.1 编译程序
使用交叉编译工具链编译好程序,然后将其通过nfs的方式共享给开发板使用
$ arm-linux-gcc test.c -g # 加上-g选项2.2 启动gdbserver
假设开发板上已经安装好gdbserver工具,并且上面交叉编译好的程序a.out已经通过nfs共享到开发板,则可以启动gdbserver如下
$ gdbserver 192.168.1.198:2345 a.out # 192.168.1.198为PC的IP,可略,2345为端口号(可以改为其它可用值);a.out为开发板当前目录下的程序 $ gdbserver :2345 a.out # 同上,只是略去了PC的IP2.3 启动arm-linux-gdb并连接开发板
假设在PC已经安装好arm-linux-gdb交叉调试工具,则可以启动并调试开发板上的a.out
$ arm-linux-gdb a.out # a.out在PC上也要有一份(和开发板上的那个a.out是完全一样的!),否则不能设置断点2.4 开始调试
这时候可以使用跟PC调试时同样的方法去调试程序了。需要注意的是,这时不能使用r命令来执程序,而要使用c来代替。
3、core file
在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数[9]。对于core file,参考资料[12]P234、P236和P248都有描述。
3.1 生成core file[9]
$ ulimit -c # 查看core文件的生成开关。若结果为0,则表示关闭了此功能,不会生成core文件。 $ ulimit -c filesize # 限制core文件的大小,如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件。在调试此core文件的时候,gdb会提示错误。 $ ulimit -c unlimited # core文件的大小不受限制,为了调试,应该使用这个设置。3.2 查看core file[9]
查看core file,需要借助gdb工具,使用其bt或者where命令。关于加载core file和可执行文件,有几种不同的调用方式。
3.2.1 调用方式1
$ gdb a.out (gdb) core-file corefile (gdb) bt # backtrace
3.2.2 调用方式2
$ gdb -core=corefile (gdb) file a.out (gdb) bt3.2.3 调用方式3
$ gdb -c corefile (gdb) file a.out (gdb) bt
3.2.4 where命令
$ gdb -c core (gdb) where
3.3 嵌入式core文件调试[9]
3.3.1 直接在开发板上调试
如果开发板上有gdb工具,可以直接使用它来进行core调试。
3.3.2 交叉调试
如果开发板上没有gdb工具,可将开发板的环境(依赖库)、可执行文件和core文件拷贝到PC的Linux下进行调试。这时使用的是arm-linux-gdb,方法同3.2。另外,还需要在待运行gdb的路径下建立.gdbinit,配置文件内容:
set solib-absolute-prefix /home/liyihai/embeddedSystem/arago-2011.09/armv5te/bin # YOUR_CROSS_COMPILE_PATH set solib-search-path /home/liyihai/embeddedSystem/arago-2011.09/armv5te/lib # YOUR_DEVELOPER_TOOLS_LIB_PATH handle SIG32 nostop noprint pass这样子在调试时就不会说找不到依赖库了。
参考资料
[1]gdb源码下载
[2]嵌入式Linux的GDB调试环境的建立
[3]GDB+GdbServer: ARM程序调试
[4]GDB 命令详细解释
[5]GDB十分钟教程
[6]Linux gdb设置和管理断点
[7]gdbserver远程调试
[8]用gdb和gdbserver远程调试tq2440
[9]linux下core文件调试方法
[10]Linux下调试core文件的方法
[11]Linux下core文件调试方法
[12]《UNIX环境高级编程》2nd
[13]Linux core dump详解