GDB 和strace 使用和移植

来源:互联网 发布:g92调多头螺纹怎么编程 编辑:程序博客网 时间:2024/06/16 09:43

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源码版本7.2:下载地址 http://202.109.143.228:82/down/gdb-7.2.tar.gz或http://ftp.gnu.org/gnu/gdb/gdb-7.3.1.tar.gz(官网最新版)
 
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库
 
$cp ncurses-5.8.tar.gz /tmp
 
$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的交叉编译和简单使用。
 
 
 
strace4.6下载地址: http://nchc.dl.sourceforge.net/project/strace/strace/4.6/strace-4.6.tar.xz
 
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拷贝到开发板上。
 
 
 
$strace -f ls  //查看ls文件的系统调用,这里就不在截图了。

0 0
原创粉丝点击