GDB和strace的使用及移植


GDB章节
 
GDB是linux下常用的应用程序调试工具,本文介绍linux环境下一些常用的调试命令,并通过交叉编译移植GDB到Android开发板上。
 
主机系统环境:Linux TS-Server 2.6.32-21-generic-pae #32-Ubuntu SMP Fri Apr 16 09:39:35 UTC 2010 i686 GNU/Linux
目标板环境:Linux localhost 3.0.31-00003-OMAP-Android-01831-gf9b35ae #4 SMP PREEMPT Fri Sep 7 08:19:55 CST 2012 armv7l GNU/Linux
交叉编译工具版本:gcc version 4.4.1 (Sourcery G++ Lite 2010q1-202)(target:arm-none-linux-gnueabi)
GDB依赖库ncurses:下载地址 http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.8.tar.gz
 
环境变量说明:
export CC_PATH=/home/lichao/android/arm/opt/CodeSourcery/bin  //交叉编译工具链路径
export SRC_GDB=~/Download
 
一.GDB常用命令命令介绍:
gdb>list  //列出源码,默认源码文件和执行文件同路径
gdb><回车> //重复上次命令
gdb>break 10 //在第十行下断点
gdb>break func //在函数func入口下断点
gdb>info break //查看断点信息
gdb>info args //打印当前函数参数名和值
gdb>info locals //打印当前函数所有局部变量和值
gdb>disassemblefunc //查看函数func的汇编代码
gdb>run //运行程序
gdb>next //单条语句执行
gdb>n //等同next
gdb>continue //继续运行
gdb>p i //打印变量值,等同于print
gdb>bt //查看函数堆栈
gdb>shell <command>  //执行shell命令
gdb>clear<linenum> //清除断点,相关命令有delete/disable/enable
gdb>step //单步运行
 
 
二.移植GDB到Omap4460 开发板(跑的是Android 4.0)
1.解压配置
$mkdir ~/gdb
$cp $SRC_GDB/gdb-7.2.tar.gz ~/gdb
$cd ~/gdb
$tar xvf gdb-7.2.tar.gz -C .
$cd gdb-7.2
$export PATH=$CC_PATH:$PATH //追加交叉编译工具链至path中,请确保成功添加
$./configure --host=arm-none-linux-gnueabi --prefix=/home/lichao/gdb/arm_gdb
(上面指定的host表示目标主机所需的编译器前缀,而prefix有可能设置全路径而不是带环境变量的路径安装路径,请注意)
以上都ok,如果有问题,请检查你的交叉编译工具链环境变量和相关操作是否正确。
 
2.交叉编译GDB
$make -j4
接下来,在本环境下将会遇到错误:
configure: WARNING: no enhanced curses library found; disabling TUI
checking for library containing tgetent... no
configure: error: no termcap library found
make[1]: *** [configure-gdb] Error 1
make[1]: Leaving directory `/home/lichao/android/arm/temp/gdb-7.2'
make: *** [all] Error 2
 
针对上述情况网络上的方法通常有2种:
1.如果是ubuntu用户,直接sudo apt-get install libncurses5-dev
2.下载termcap源码并交叉编译后得到库文件libtermcap.a。
 
本文通过上面两种方法得知都有问题,第一种是误认为交叉编译缺少的库为x86的libncurses字符图像库,第二种忽略了版本库的兼容问题。
其实所有的问题我们都可以通过查看config.log日志找到解决办法。
$vi gdb/config.log
 
2065 configure:9592: arm-none-linux-gnueabi-gcc -o conftest -g -O2     conftest.c -lcurses  -lm    >&5
2066 /home/lichao/android/arm/opt/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: cannot      find -lcurses
.....
2283 configure:9698: arm-none-linux-gnueabi-gcc -o conftest -g -O2     conftest.c -ltermcap  -lm    >&5
.....
2291 /home/lichao/android/arm/opt/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: skippin     g incompatible /home/lichao/android/arm/opt/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/usr/lib/libtermcap.a when searching for -lte     rmcap
2292 /home/lichao/android/arm/opt/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: cannot      find -ltermcap
2293 collect2: ld returned 1 exit status
 
从上面的2065行和2283行可以看出,编译器会试着通过命令去编译一个叫做conftest.c的文件,然后从编译结果看是否成功,如果不成功将会返回错误。
conftest.c内容如下;
 
 char waddstr ();
 int main ()
 {
      return waddstr ();
 }
其实就是通过连接库curses或者termcap库,看看能否成功编译该文件,如果能成功编译,说明存在该库。
 
这就明朗了,接下来,因为我们用的gdb版本较高,直接使用高本本的libncurses库尝试。
 
下载ncurses5.8源码,交叉编译curses库
$cd /tmp
$tar xvf ncurses-5.8.tar.gz -C .
$cd ncurses-5.8
$./configure --host=arm-none-linux-gnueabi --prefix=/tmp/arm_ncurses
$make -j4
$make install
最后成功编译出curses库,如图:
 
将这些库复制到CC_PATH的标准库目录中,确保能正确找到,可以通过如下方法找到标准库路径
$arm-none-linux-gnueabi-gcc -print-file-name=libc.a (版本不同可能命令的格式不相同,请--help查看用法)
结果如下:
/home/lichao/android/arm/opt/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a
那么我们将库复制到这个目录下:
$cp /tmp/arm_ncurses/lib/* /home/lichao/android/arm/opt/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/usr/lib
同理,复制头文件到标准路径;
$cp /tmp/arm_ncurses/include/* /home/lichao/android/arm/opt/CodeSourcery/bin/../arm-none-linux-gnueabi/libc/usr/include -rf
(复制整个ncurses文件夹)
 
(到这里,可以将config.log中写入的conftest.c文件内容提出来编译试试,通过后就可以往后走了)
接下来继续编译:
$make -j4
$make install
如此,便可正确生成我们需要的gdb文件,将生成的4个文件和所依赖的库文件拷贝到开发板相应的目录中即可。
 
本文中为了移植到开发板而不需要另外拷贝库到开发板中,将gdb编译为static。
$./configure --host=arm-none-linux-gnueabi --prefix=/tmp/arm_ncurses //生成Makefile
$vi Makefile   //找到376行,这里也可以直接在./configure的时候加上参数CFLAGS的static参数。
 
$make -j4
$make install
 
最终编译结果如下图
 
这里的gdb千万不要为了减少体积进行arm-none-linux-strip gdb,否则会导致gdb无法载入文件,找不到文件的symbol.
 
下面我们用gdb在开发板上测试一下。源码如下:
 
$arm-none-linux-gnueabi-gcc -g test.c  //记得加-g
$cp a.out ~/nfs/android/systen/bin   //拷贝到开发板
 
 
上面可以看出在源代码的第5行出现了段错误函数func()参数1为空指针!
 
下面调试android的C++程序,注意,在编译程序前(即mm)时候记得在Android.mk文件中的LOCAL_CFLAG 加上-g选项,如图:
 
$mm
编译结果如下:
 
注意到有4个codec_test目标文件生成,那么哪个是我们需要的呢,这里可以通过du命令查看大小得到。
通过对比上面的几个文件,target Executable 指向的文件最大,因为里面包含了调试信息,而install的文件是经过strip剪切过的,去掉了调试信息。
所以需要在开发板上调试的话需要复制target Executable 指向的文件。方法和上面类似,这里不再举例。
 
 
                                                                                         strace使用
strace 主要用于程序系统调用跟踪,网上也有很多这样的例子,本文主要介绍了strace的交叉编译和简单使用。
 
xz解压程序5.0.3源码地址: http://tukaani.org/xz/xz-5.0.3.tar.bz2
 
一.strace常用命令
-p 跟踪指定的进程
-f 跟踪由fork子进程系统调用
-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
-r 打印每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
-c 统计每种系统调用所执行的时间,调用次数,出错次数。
-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出
 
 
二.交叉编译strace
1.下载xz解压包,解压
$tar xvf xz-5.0.3.tar.bz2
$./configure //生成Makefile
$make
$make install 
接下来解压strace
$xz -d strace-4.6.tar.xz  //得到strace-4.6.tar
$tar xf strace-4.6.tar
交叉编译strace
$cd strace-4.6
$./configure --host=arm-none-linux-gnueabi --prefix=/home/lichao/temp/strace
$make
$make install
 
这里本文生成静态的strace文件,方便使用。方法和上面的GDB一样。修改Makefile。
最后将strace/bin下的strace和strace-graph拷贝到开发板上。
 
                     
                                                                                                                                                                  By: LiChao  
                                                                                                                                                                 
                                                                                                                                                                               2012.11.20
 
posted @ 2012-11-20 22:44  凡人修行  阅读(2031)  评论(0编辑  收藏  举报