GDB调试

来源:互联网 发布:tensorflow finetune 编辑:程序博客网 时间:2024/06/01 07:59
1. tftp将附件gdbserver拷贝到AP的/bin目录
2. AP上执行 gdbserver 10.0.0.201:2345 clid启动调试clid
3. 在host主机(即我们的编译服务器)上
   mips-linux-gdb进去gdb
  (gdb) target remote 10.0.0.201:2345
  再往下就是熟悉的gdb调试方法

首先确保系统down掉后能够产生core文件,可使用ulimit -c 查看,目前系统已默认ulimit -c unlimited。

产生的core文件已包含命令名并且路径已指定至/tmp下,使用tftp工具将其导出至编译服务器相应进程的目录下。
然后进入该目录,使用mips-linux-gdb 进程名 core文件 进行gdb调试。
例如,对于clid进程产生的core-clid-**文件,将其放至编译服务器/wisesystem/apps/cli 目录下,进入该目录,
使用mips-linux-gdb clid core-clid-**, 进行gdb调试。

set solib-absolute-prefix /home/chengtong/AP0318/infra/wise3000/atheros_9344/rootfs
正常情况在gdb下,可使用bt查看程序运行至哪个位置出了错,p symbol查看当前变量值。
而对于一些段错误会导致corrupt stack从而无法产看栈信息,造成segment fault,一般情况下是内存访问越界、非法指针/堆栈溢出等。


gdb查看指定地址的内存地址的值:examine 简写 x-----使用gdb > help x 来查看使用方式

     x/  (n,f,u为可选参数)

 n: 需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义

  f:显示格式

               x(hex) 按十六进制格式显示变量。                                d(decimal) 按十进制格式显示变量。

               u(unsigned decimal) 按十进制格式显示无符号整型。               o(octal) 按八进制格式显示变量。

               t(binary) 按二进制格式显示变量。                               a(address) 按十六进制格式显示变量。

               c(char) 按字符格式显示变量。                                   f(float) 按浮点数格式显示变量

 u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示

               b:1 byte     h:2 bytes     w:4 bytes g:8 bytes

     比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。

    from http://www.cnblogs.com/super119/archive/2011/03/26/1996125.html


gdb打印表达式的值:print/f 表达式

f是输出的格式,x/d/u/o/t/a/c/f


表达式可以是当前程序的const常量,变量,函数等内容,但是GDB不能使用程序中所定义的宏

查看当前程序栈的内容: x/10x $sp-->打印stack的前10个元素

查看当前程序栈的信息: info frame----list general info about the frame

查看当前程序栈的参数: info args---lists arguments to the function

查看当前程序栈的局部变量: info locals---list variables stored in the frame

查看当前寄存器的值:info registers(不包括浮点寄存器) info all-registers(包括浮点寄存器)

查看当前栈帧中的异常处理器:info catch(exception handlers)


嵌入式arm linux环境中gdb+gdbserver调试
一.前言
嵌入式Linux系统中,应用开发过程中,很多情况下,用户需要对一个应用程序进行反复调试,特别是复杂的程序。采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,通常采用gdb+gdbserver的方式进行调试。 Gdbserver在目标系统中运行,gdb则在宿主机上运行。
目标系统必须包括gdbserver程序,宿主机也必须安装gdb程序。在此我们还不能直接采用linux发行版自带的gdb,需要交叉编译gdb和gdbserver。
二.编译gdb和gdbserver工具
下载最新版本的gdb-6.8.tar.gz,可以到ftp://ftp.gnu.org/gnu/gdb下载.
准备好自己的工作目录,如下示
/home/user/gdb
            |--gdb-6.8
            |--obj-gdb
                    |--build
            |--obj-gdbserver
                    |--build
            |--bin
脚本obj-gdb/build内容如下:
#!/bin/sh
../gdb-6.8/configure --target=arm-linux --enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext
make
echo "done"
脚本obj-gdbserver/build内容如下:
#!/bin/sh
CC=/opt/toolchain/arm-linux/bin/arm-linux-gcc 
../gdb-6.8/gdb/gdbserver/configure --host=arm-linux --without-included-regex --without-included-gettext
echo "done"
开始编译:
(1) cd obj-gdb
    ./build
(2) cd obj-gdbserver
    ./build
    这时会生成Makefile,修改Makefile如下
    LDFLAGS= -static
    然后make
(3) cd bin
    cp ../obj-gdb/gdb/gdb .
    cp ../obj-gdbserver/gdbserver .
    arm-linux-strip gdbserver
(4) 好了bin目录下就是最终编译出来的gdb+gdbserver了
三.gdbserver使用
(1) 目标机中
    执行命令gdbserver 10.0.12.144:1234 test
    注意test在编译的时候是要加-g选项的
(2) 宿主机中
    gdb test
    再输入命令target remote 10.0.12.143:1234
    接下来就可以gdb的调试了
(3) 说明
    目标机IP:10.0.12.143
    宿主机IP: 10.0.12.144

   端口是随意指定的,只要两端保持一致就行了
    test程序两端也必须相同
(stavy)

出处http://yiluohuanghun.blog.51cto.com/3407300/1182134

4、调试步骤
1、交叉编译,带参数-gstabs 或 -g 加入调试信息。
假设要调试的程序为hello.c。
#arm-linux-gcc -g hello.c -o hello
2、在Target Board开启gdbserver
#gdbserver  <host-ip>:2345 hello   (我的host-ip是192.168.0.178)
gdbserver开始监听2345端口(你也可以设其他的值),然后启动hello,你会看到“Process test created:pid=88”
3、回到Host端
#export PATH=$PATH:/home/cby/arm-gdb/bin(arm-linux-gdb的路径)
#arm-linux-gdb hello
最后一行显示:This GDB was configured as “--host=i686-pc-linux-gnu,--target=arm-linux”...
说明此gdb在X86的Host上运行,但是调试目标是ARM代码。
(gdb)target remote <target-board-ip>:2345    (我的target-board-ip is 192.168.0.177)
注意:你的端口号必须与gdbserver开启的端口号一致,这样才能进行通信。
建立链接后,就可以进行调试了。调试在Host端,跟gdb调试方法相同。注意的是要用“c”来执行命令,不能用“r”。因为程序已经在Target Board上面由gdbserver启动了。结果输出是在Target Board端,用超级终端查看。
 
5、下面就可以正式调试了!我们先来说一下几个常用的命令
(1)l:列出所有源代码
(2)break main:在main处打断点
         break test_debug.c:11:在test_debug.c的11行打断点
(3)c:运行到断点处
(4)step:单步执行
(5)next:单步执行,但是step会进入函数里面,但是next不会
(6)print a:打印a这个变量的值
(6)quit:退出,输入此命令则开发板上的gdbserver也退出
更详细的命令,我们在下一节里面会进一步来讲讲的!
 
6、另一种调试方法
让程序在开发板上直接运行,当它发生错误时,令它产生core dump文件
然后使用gdb根据core dump文件找到发生错误的地方
 
在ARM板上:
1. ulimit -c unlimited
2. 执行应用程序 : 程序出错时会在当前目录下生成名为core的文件
 
在PC上:
3、首先将core文件拷贝到pc机上
     然后:/bin/arm-linux-gdb ./test_debug ./core
 
打印出如下信息:
 
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/share/jz2440/test_debug...done.
[New LWP 748]
warning: `/lib/libc.so.6': Shared library architecture unknown is not compatible with target architecture arm.
warning: `/lib/ld-linux.so.2': Shared library architecture unknown is not compatible with target architecture arm.
Core was generated by `./test_debug'.
Program terminated with signal 11, Segmentation fault.
#0  0x000084ac in C (p=0x0) at test_debug.c:6
6               *p = 0x12;
 
4、bt:可以显示调用关系
 
#0  0x000084ac in C (p=0x0) at test_debug.c:6
#1  0x000084d0 in B (p=0x0) at test_debug.c:12
#2  0x000084f0 in A (p=0x0) at test_debug.c:17
#3  0x00008554 in main (argc=1, argv=0xbeb32eb4) at test_debug.c:34



0 0
原创粉丝点击