How to generate gcc debug symbol outside the build target?

How to generate gcc debug symbol outside the build target?

1. how to strip elf.

2. how to separate debug information from elf files.

3. how to use debug information in gdb(or ida pro).

ida pro : file -> load file -> DBG file

4. how to merge debug information into elf files.

How debuggers work: Part 3 – Debugging information

About debugging information.

How to find functions, variables and line number based on debugging information(dwarf)

关于SIGSEGV错误及处理方法

关于SIGSEGV错误及处理方法
今天编程遇到了SIGSEGV错误,比较困惑,所以找了些资料,总结一下:

(1)官方说法是:
SIGSEGV — Segment Fault. The possible cases of your encountering this error are:

1.buffer overflow — usually caused by a pointer reference out of range.

2.stack overflow — please keep in mind that the default stack size is 8192K.

3.illegal file access — file operations are forbidden on our judge system.




(2)SIGBUS与SIGSEGV信号的一般区别如下:

1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。

2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。




(3)Linux的mmap(2)手册页

————————————————————————–
使用映射可能涉及到如下信号

SIGSEGV

试图对只读映射区域进行写操作

SIGBUS

试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以前有文件内容对应,现在为另一进程截断过的内存区域。
————————————————————————–




弄清楚错误以后,就要查找产生错误的根源,一般我用以下两种方法:

(1)gcc -g 编译
ulimit -c 20000
之后运行程序,等core dump
最后gdb -c core <exec file>

     来查调用栈

(2)使用strace execfile,运行程序,出错时会显示那个系统调用错

转自:http://blog.csdn.net/brace/article/details/1102422

使用gdb和gdbserver调试Android C/C++程序

1,http://www.gnu.org/software/gdb/download/,下载最新版本的gdb源代码包,我使用的是gdb-7.6.tar.gz,使用tar命令进行解包(tar -xvzf gdb-7.6.tar.gz),cd进gdb-7.6/gdb目录,使用vi找到remote.c中的如下代码:
if(buf_len > 2 * rsa->sizeof_g_packet)

error(_(“Remote ‘g’ packet reply is too long: %s”),rs->buf);

将上面两行注释掉,添加如下代码

if(buf_len > 2 * rsa->sizeof_g_packet)
{
rsa->sizeof_g_packet = buf_len;
for(i = 0; i < gdbarch_num_regs(gdbarch); i++)
{
if(rsa->regs[i].pnum == -1)
continue;
if(rsa->regs[i].offset >= rsa->sizeof_g_packet)
rsa->regs[i].in_g_packet = 0;
else
rsa->regs[i].in_g_packet = 1;
}
}
使用如下命令对代码进行配置、编译和安装

./configure –target=arm-linux –prefix=/usr/local/arm-gdb -v

make

make install

2,gdbserver使用android4.2模拟器中自带的版本(v7.1)

3,将NDK编译好的C/C++可执行程序,上传到模拟器中/data/test目录下,假设可执行程序的名称为testHello。

4,使用命令:gdbserver :7000 /data/test/testHello 启动模拟器端的调试。

5,启动arm-linux-gdb之前,使用vi打开~/.bash_profile文件,在其中添加:

export PATH=$PATH:/usr/local/arm-gdb/bin,以便在程序的其他目录可以直接启动arm-linux-gdb程序

6,cd至ndk编译好的testHello文件所在目录

7,使用如下命令进行端口映射:adb forward tcp:7000 tcp:7000,将模拟器的7000端口和本机的7000端口进行映射

8,使用命令:arm-linux-gdb testHello启动gdb调试

9,使用target remote :7000 链接模拟器中gdbserver启动的服务。

10,自此,我们就可以使用gdb命令进行代码调试了。

gdb running in android operating system

Goal

Run a program under gdb

Download/install gdb

Run the commands at an adb command line. This will require a working busybox (tar, wget) in your path. Running under a terminal will require adjusting your paths.

  • cd /data/local/tmp
  • wget http://dan.drown.org/android/gdb-static.tar.gz
  • tar zxf gdb-static.tar.gz

Run a program under gdb

Here, I created a small program that crashes and put it in /data/local/tmp

  • /data/local/tmp/bin/gdb [path to program]

Below is a sample session, typed commands are in bold

Reading symbols from /data/local/tmp/crash...done.
(gdb) run
Starting program: /data/local/tmp/crash
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.

Program received signal SIGSEGV, Segmentation fault.
0x0000859c in main ()
(gdb) info regi
r0             0x1      1
r1             0xbecc6b34       -1093899468
r2             0x0      0
r3             0x0      0
r4             0x8580   34176
r5             0xbecc6b34       -1093899468
r6             0x1      1
r7             0xbecc6b3c       -1093899460
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0xbecc6b14       -1093899500
r12            0x400d200c       1074601996
sp             0xbecc6b08       0xbecc6b08
lr             0x4012d169       1074975081
pc             0x859c   0x859c <main+28>
cpsr           0x60070010       1611071504
(gdb) x/i $pc
=> 0x859c <main+28>:    str     r2, [r3]

You can see that this program is trying to store the value in r2 (0x0) in the address pointed to by r3 (0x0), which resulted in the segmentation fault.

here: gdb-static.tar 下载

GDB + gdbserver 远程调试android native code

分类: C/C++

 

以调试模拟器中的native library code为例。

Host: ubuntu
Target: Android ICS

1.将gdbserver放入设备。

确保系统有arm-*-gdb,及存在设备端将要运行的gdbserver,gdbserver可以由google ndk中获取,在ndk的如下目录可以找到这个文件:

 

点击(此处)折叠或打开

  1. android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt

 

然后,通过adb shell进入设备,在/data下创建bin 目录:

点击(此处)折叠或打开

  1. hanpfei@hanpfeiF6Ve:/mnt/android_proj/android_src$ adb shell
  2. # mkdir /data/bin/

 

再通过adb push命令将gdbserver 放入设备:

 

点击(此处)折叠或打开

  1. hanpfei@hanpfei-F6Ve:/mnt/android_proj/softwares/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt$ ls
  2. gdbserver linux-x86
  3. hanpfei@hanpfei-F6Ve:/mnt/android_proj/softwares/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt$ adb remount
  4. remount succeeded
  5. hanpfei@hanpfei-F6Ve:/mnt/android_proj/softwares/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt$ adb push gdbserver /data/bin/
  6. 543 KB/s (125208 bytes in 0.225s)

2、在设备端启动gdbserver并attach到所要debug的进程

 

点击(此处)折叠或打开

  1. system 1168 37 156620 31924 ffffffff 40011384 S com.android.keychain
  2. app_34 2758 37 158360 34572 ffffffff 40011384 S com.hanpfei.text
  3. root 2774 617 900 348 00000000 40010438 R ps
  4. gdbserver :1234 –attach 2758
  5. Attached; pid = 2758
  6. Listening on port 1234

 

gdbserver 后面跟的第一个参数为端口号,之后的–atach 为gdbserver的选项,之后的数字为所要调试的进程的PID。

3、在Host端启动arm-*-gdb

网上有高手build的各种交叉编译工具链来方便大家的嵌入式开发,单这个工具链中的gdb命令实际文件名称的前缀和后缀都会是相同的,中间的那个*可以见到各种各样的形式,比如linux,linux-androideabi,none-linux-gnueabi等等。

 

点击(此处)折叠或打开

  1. hanpfei@hanpfei-F6Ve:/mnt/android_proj/softwares/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin$ ./arm-linux-androideabi-gdb
  2. GNU gdb 6.6
  3. Copyright (C) 2006 Free Software Foundation, Inc.
  4. GDB is free software, covered by the GNU General Public License, and you are
  5. welcome to change it and/or distribute copies of it under certain conditions.
  6. Type “show copying” to see the conditions.
  7. There is absolutely no warranty for GDB. Type “show warranty” for details.
  8. This GDB was configured as “–host=i386-linux-gnu –target=arm-elf-linux”.
  9. (gdb) shell adb forward tcp:1234 tcp:1234
  10. (gdb) target remote localhost:1234
  11. Remote debugging using localhost:1234
  12. [New Thread 2758]
  13. Malformed packet(b) (missing colon): re:0;
  14. Packet: ‘T050b:7476b6be;0d:b874b6be;0f:84130140;thread:ac6;core:0;’
  15. (gdb)

使用ndk中所带的交叉编译工具链,会出现报错信息,意为畸形数据包: 

 

点击(此处)折叠或打开

  1. [New Thread 2758]
  2. Malformed packet(b) (missing colon): re:0;
  3. Packet: ‘T050b:7476b6be;0d:b874b6be;0f:84130140;thread:ac6;core:0;’

同时,在设备端也可以看到有如下的输出,来显示着这server端与client端难以协调的步调:

 

点击(此处)折叠或打开

  1. # gdbserver :1234 –attach 2758
  2. Attached; pid = 2758
  3. Listening on port 1234
  4. Remote debugging from host 127.0.0.1
  5. readchar: Got EOF
  6. Remote side has terminated connection. GDBserver will reopen the connection.
  7. Listening on port 1234

 

出现这样的状况,是由于gdbserver和arm-*-gdb版本不对应所致。由上面我们启动arm-linux-androideabi-gdb时的输出可以看到,其版本为GNU gdb 6.6。在设备上,我们可以查看gdbserver的版本信息:

 

 

点击(此处)折叠或打开

  1. gdbserver —version
  2. GNU gdbserver (GDB) 7.1-android-gg2
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. gdbserver is free software, covered by the GNU General Public License.
  5. This gdbserver was configured as “arm-elf-linux”
  6. #

我们可以看到gdbserver版本为GNU gdbserver (GDB) 7.1-android-gg2。这也就是症结所在。 

我们可以换用和gdbserver版本较为接近的arm-*-gdb。此时在host端所需输入的命令及相应的输出如下:

 

点击(此处)折叠或打开

  1. hanpfei@hanpfei-F6Ve:~/develop_tool_chain/arm-2011.03/bin$ ./arm-none-linux-gnueabi-gdb
  2. GNU gdb (Sourcery G++ Lite 2011.03-41) 7.2.50.20100908-cvs
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type “show copying”
  7. and “show warranty” for details.
  8. This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-none-linux-gnueabi”.
  9. For bug reporting instructions, please see:
  10. <https://support.codesourcery.com/GNUToolchain/>.
  11. (gdb) shell adb forward tcp:1234 tcp:1234
  12. (gdb) target remote localhost:1234
  13. Remote debugging using localhost:1234
  14. 0x40011384 in ?? ()
  15. (gdb)
启动gdb,然后是执行shell命令(shell adb forward tcp:1234 tcp:1234) , 以完成端口映射的任务,靠前的那个为local端的端口,靠后的那个为remote端的。
于此同时,在设备端也将看到有如下的输出:

 

 

点击(此处)折叠或打开

  1. Listening on port 1234
  2. Remote debugging from host 127.0.0.1

这即是表明,gdb client端和server端有成功的链接。

 

接下来通过file命令来加载将要调试的可执行文件,对于android application来说,均为 out/target/product/generic/symbols/system/bin/app_process 这个文件,及设置搜索solib的搜索路径

点击(此处)折叠或打开

  1. (gdb) target remote localhost:1234
  2. Remote debugging using localhost:1234
  3. 0x40011384 in ?? ()
  4. (gdb) /mnt/android_proj/android_src/out/target/product/generic/symbols/system/bin/app_process
  5. Undefined command: “”. Try “help”.
  6. (gdb) file /mnt/android_proj/android_src/out/target/product/generic/symbols/system/bin/app_process
  7. A program is being debugged already.
  8. Are you sure you want to change the file? (y or n) y
  9. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/bin/app_process…done.
  10. (gdb) set solib-search-path /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib
  11. warning: Could not load shared library symbols for 3 libraries, e.g. /system/bin/linker.
  12. Use the “info sharedlibrary” command to see the complete listing.
  13. Do you need “set solib-search-path” or “set sysroot”?
  14. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libc.so…done.
  15. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libc.so
  16. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstdc++.so…done.
  17. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstdc++.so
  18. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libm.so…done.
  19. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libm.so
  20. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/liblog.so…done.
  21. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/liblog.so
  22. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcutils.so…done.
  23. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcutils.so
  24. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libz.so…done.
  25. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libz.so
  26. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libutils.so…done.
  27. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libutils.so
  28. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbinder.so…done.
  29. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbinder.so
  30. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libexpat.so…done.
  31. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libexpat.so
  32. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcrypto.so…done.
  33. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcrypto.so
  34. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libgabi++.so…done.
  35. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libgabi++.so
  36. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libicuuc.so…done.
  37. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libicuuc.so
  38. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libicui18n.so…done.
  39. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libicui18n.so
  40. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libssl.so…done.
  41. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libssl.so
  42. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstlport.so…done.
  43. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstlport.so
  44. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnativehelper.so…done.
  45. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnativehelper.so
  46. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnetutils.so…done.
  47. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnetutils.so
  48. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2_dbg.so…done.
  49. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2_dbg.so
  50. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libEGL.so…done.
  51. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libEGL.so
  52. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libwpa_client.so…done.
  53. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libwpa_client.so
  54. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libhardware_legacy.so…done.
  55. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libhardware_legacy.so
  56. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libpixelflinger.so…done.
  57. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libpixelflinger.so
  58. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libhardware.so…done.
  59. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libhardware.so
  60. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libemoji.so…done.
  61. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libemoji.so
  62. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libjpeg.so…done.
  63. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libjpeg.so
  64. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libskia.so…done.
  65. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libskia.so
  66. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libui.so…done.
  67. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libui.so
  68. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2.so…done.
  69. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2.so
  70. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libgui.so…done.
  71. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libgui.so
  72. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcamera_client.so…done.
  73. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libcamera_client.so
  74. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libsqlite.so…done.
  75. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libsqlite.so
  76. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libdvm.so…done.
  77. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libdvm.so
  78. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv1_CM.so…done.
  79. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv1_CM.so
  80. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libETC1.so…done.
  81. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libETC1.so
  82. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libsonivox.so…done.
  83. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libsonivox.so
  84. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_foundation.so…done.
  85. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_foundation.so
  86. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmedia.so…done.
  87. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmedia.so
  88. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnfc_ndef.so…done.
  89. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libnfc_ndef.so
  90. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libusbhost.so…done.
  91. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libusbhost.so
  92. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libharfbuzz.so…done.
  93. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libharfbuzz.so
  94. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libandroid_runtime.so…done.
  95. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libandroid_runtime.so
  96. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libvorbisidec.so…done.
  97. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libvorbisidec.so
  98. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_yuv.so…done.
  99. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_yuv.so
  100. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libdrmframework.so…done.
  101. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libdrmframework.so
  102. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libchromium_net.so…done.
  103. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libchromium_net.so
  104. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_amrnb_common.so…done.
  105. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_amrnb_common.so
  106. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_enc_common.so…done.
  107. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_enc_common.so
  108. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_avc_common.so…done.
  109. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright_avc_common.so
  110. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright.so…done.
  111. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libstagefright.so
  112. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmtp.so…done.
  113. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmtp.so
  114. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libexif.so…done.
  115. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libexif.so
  116. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmedia_jni.so…done.
  117. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libmedia_jni.so
  118. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbcc.so…done.
  119. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbcc.so
  120. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbcinfo.so…done.
  121. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libbcinfo.so
  122. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libRS.so…done.
  123. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libRS.so
  124. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/librs_jni.so…done.
  125. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/librs_jni.so
  126. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libandroid.so…done.
  127. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libandroid.so
  128. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libwebcore.so…done.
  129. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libwebcore.so
  130. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/lib_renderControl_enc.so…done.
  131. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/lib_renderControl_enc.so
  132. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2_enc.so…done.
  133. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv2_enc.so
  134. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv1_enc.so…done.
  135. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libGLESv1_enc.so
  136. Reading symbols from /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libOpenglSystemCommon.so…done.
  137. Loaded symbols for /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib/libOpenglSystemCommon.so
  138. warning: Unable to find dynamic linker.
  139. GDB will be unable to debug shared library initializers
  140. and track explicitly loaded dynamic code.
  141. (gdb) set solib-absolute-prefix /mnt/android_proj/android_src/out/target/product/generic/symbols/system/lib
  142. warning: Unable to find dynamic linker.
  143. GDB will be unable to debug shared library initializers
  144. and track explicitly loaded dynamic code.
  145. (gdb)
此处所设置的路径下应该存在有编译好的带有符号的链接库文件,此处的设置,回事gdb读取这些库文件中的符号。可以通过directory命令来为gdb增加搜索原代码的路径。

之后,即可如调试PC端的C/C++ code一样,下断点,执行,查看内存内容,查看back trace等,来进行对library的debug工作: 

 

点击(此处)折叠或打开

  1. (gdb) break HB_ShapeItem
  2. Note: breakpoint 1 also set at pc 0x4094bf2c.
  3. Breakpoint 2 at 0x4094bf2c: file external/harfbuzz/src/harfbuzz-shaper.cpp, line 1340.
  4. (gdb) info break
  5. Num Type Disp Enb Address What
  6. 2 breakpoint keep y 0x4094bf2c in HB_ShapeItem(HB_ShaperItem*) at external/harfbuzz/src/harfbuzz-shaper.cpp:1340
  7. (gdb) continue
  8. Continuing.
  9. Breakpoint 2, HB_ShapeItem (shaper_item=0xbeb6729c) at external/harfbuzz/src/harfbuzz-shaper.cpp:1340
  10. 1340     if (shaper_item->num_glyphs < shaper_item->item.length) {
  11. (gdb) n
  12. 1338    {
  13. (gdb) s
  14. 1340     if (shaper_item->num_glyphs < shaper_item->item.length) {
  15. (gdb) list
  16. 1335    }
  17. 1336
  18. 1337    HB_Bool HB_ShapeItem(HB_ShaperItem *shaper_item)
  19. 1338    {
  20. 1339     HB_Bool result = false;
  21. 1340     if (shaper_item->num_glyphs < shaper_item->item.length) {
  22. 1341     shaper_item->num_glyphs = shaper_item->item.length;
  23. 1342     return false;
  24. 1343     }
  25. 1344     assert(shaper_item->item.script < HB_ScriptCount);
  26. (gdb)

 

 

gdb常用调试命令

0、查看程序源代码

directory(dir) DIR

Add directory DIR to beginning of search path for source files.Forget cached info on

          source file locations and line positions. DIR can also be $cwd for the current working directory, or $cdir for
          the directory in which the source file was compiled into object code.  With no argument, reset the search path
          to $cdir:$cwd, the default.

    show directories Current search path for finding source files.
    list
    List specified function or line. With no argument, lists ten more lines
    after or around previous listing. “list -” lists the ten lines before a
    previous ten-line listing. One argument specifies a line, and ten lines
    are listed around that line. Two arguments with comma between specify
    starting and ending lines to list. Lines can be specified in these ways:
      LINENUM, to list around that line in current file,
      FILE:LINENUM, to list around that line in that file,
      FUNCTION, to list around beginning of that function,
      FILE:FUNCTION, to distinguish among like-named static functions.
      *ADDRESS, to list around the line containing that address.
     set listsize Num Set number of source lines gdb will list by default.
     disassemble Disassemble a specified section of memory.

 

1、程序运行时参数。
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。

2、运行环境。
    path <dir>  Add directory DIR(s) to beginning of search path for object files.
show paths  Current search path for finding object files.
set environment VAR [=value] 设置环境变量。如:set env HOME=/home

    unset environment VAR Cancel environment variable VAR for the program.
show environment [varname] 查看环境变量。

3、工作目录。
cd <dir> 相当于shell的cd命令。
pwd 显示当前的所在目录。

4、程序的输入输出
info terminal 显示你程序用到的终端的模式。
使用重定向控制程序输出。如:run > outfile
tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb

 

5、设置断点(BreakPoint)
我们用break命令来设置断点。正面有几点设置断点的方法:
break <function>
在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。

    break <linenum> 在指定行号设置断点。

    break +offset
break –offset
在当前行号的前面或后面的offset行停住。offiset为自然数。

    break filename:linenum  在特定源文件filename的特定行linenum处设置断点。

    break filename:function 在源文件filename的function函数的入口处停住。

    break *address          在程序运行的内存地址处停住。

    break                   break命令没有参数时,表示在下一条指令处停住。

    break … if <condition>
…可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环体中,可以设置break if i=100,表示当i为100时停住程序。

    查看断点,可使用info命令,如下所示:(注:n表示断点号)
info breakpoints [n] 
info break [n] 

    delete Delete some breakpoints or auto-display expressions.

    disable Disable some breakpoints.

    enable Enable some breakpoints.

6、设置观察点(WatchPoint)
观察点一般用来观察某个表达式(变量也是一种表达式)的值是否有变化,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
watch <expr>       为表达式(变量)expr设置一个观察点。一旦表达式值有变化,马上停住程序。
rwatch <expr>      当表达式(变量)expr被读时,停住程序。
awatch <expr>      当表达式(变量)的值被读或被写时,停住程序。
info watchpoints   列出当前所设置了的所有观察点。

7、设置捕捉点(CatchPoint)

    可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
catch <event>   当event发生时,停住程序。event可以是下面的内容:
1、throw 一个C++抛出的异常。(throw为关键字)
2、catch 一个C++捕捉到的异常。(catch为关键字)
3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
6、load 或 load <libname> 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
7、unload 或 unload <libname> 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

    tcatch <event> 设置一次捕捉点,当程序停住以后,相应捕捉点被自动删除。

 

8、运行程序

run(r) Start debugged program.。

continue(c) [ignore-count]

    fg [ignore-count]
恢复程序运行,直到程序结束,或是下一个断点到来。ignore-count表示其后
忽略断点的次数。continue,c,fg三个命令都是一样的意思。

    step N  Step program until it reaches a different source line.

Argument N means do this N times (or till program stops for another reason).单步跟踪,如果有函数调用,他会进入该函数。进入函数的前提是,此函数被编译有debug信息。

    next N
同样单步跟踪,如果有函数调用,他不会进入该函数。
后面的count参数可选,不加表示一条条地执行,加表示执行后面的count行code,然后再停住。

    kill Kill execution of program being debugged.

    set step-mode
set step-mode on
打开step-mode模式,在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。

    set step-mod off  关闭step-mode模式。

    finish            运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。

    until(u)          这个命令可以运行程序直到退出循环体。

    stepi(si)
nexti(ni)

单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码).

9、查看表达式的值

   print EXP Print value of expression EXP.

   display EXP Print value of expression EXP each time the program stops.

   undisplay Cancel some expressions to be displayed when program stops.

   info display Expressions to display when program stops, with code numbers.

   whatis EXP Print data type of expression EXP.

   ptype TYPE Print definition of type TYPE.

   info locals Local variables of current stack frame.

10、查看Call Stack

   backtrace(bt)/where COUNT Print backtrace of all stack frames, or innermost COUNT frames.

frame Select and print a stack frame.

up Select and print stack frame that called this one.

down Select and print stack frame called by this one.

info args Argument variables of current stack frame.

11、Files

   file FILE Use FILE as program to be debugged.

   add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> …]

   Load symbols from FILE, assuming FILE has been dynamically loaded. ADDR is the starting address of the file’s text.

12、共享库

   sharedlibrary Load shared object library symbols for files matching REGEXP.

   info sharedlibrary Status of loaded shared object libraries.

   set solib-search-path Set the search path for loading non-absolute shared library symbol files.This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.

   set solib-absolute-prefix Set an alternate system root. The system root is used to load absolute shared library symbol files.

13、Support

   shell Execute the rest of the line as a shell command.

   source [-s] [-v] FILE Read commands from a file named FILE.用于执行gdb调试脚本

   dump memory FILE START STOP Write contents of memory to a raw binary file. Writes the contents of memory within the range [START .. STOP) to the specifed FILE in raw target ordered bytes.

   info threads IDs of currently known threads.

   thread thread_ID Use this command to switch between threads. The new thread ID must be currently known.

   target remote ip:port Use a remote computer via a serial line, using a gdb-specific protocol. Specify the serial device it is connected to

 

gdb的help命令可帮助提供相关命令非常详细的说明。

gdb的命令比较多,陈皓老师专栏有更详细的说明:http://blog.csdn.net/haoel/article/list/7

gdb debug share lib

在开发嵌入式系统时,调试往往是一大难题。面试过不少嵌入式linux工程师,当问及调试手段时,他们的调试手段一般是两种:首先是在PC上的模拟环境中运行,若有问题,可以很方便的调试。其次,若在板子上运行时才出错,就用printf输出log信息,根据 log信息定位错误。有少部分人用gdbserver调试板子上的程序,但问到如何在共享库里设置断点时,都说没有办法。
去年,Tinyx的一个内存越界BUG,花了我2天时间。gcc的一个浮点数BUG让我查了3天时间。这类 BUG在PC上根本重现不了,在板子上用printf要花费大量的时间才能把错误的范围缩小一点。后来想了想,与其花时间去加printf,还不如把 gdbserver调试共享库的问题解决了,可以为以后的调试节省不少时间。
在网上找了半天资料,没有什么收获,看来只好自己动手研究。花了一个周末的时间去研究gdbserver的运行方式。办法是找到了,不过仍然有点麻烦,等有时间了,修改一下gdb的代码,把这个过程自动化了。
先调试运行gdbserver,对gdbserver有了一些感性认识,然后研究linux-low.c中的代码。原来,设置断点只是在对应的内存中写入断点指令(x86上为0xcc)。
gdbserver为什么不能在共享库中设置断点呢?设置断点只是写内存,调试时,所有的代码段都是可写的,在exe中可以设置断点,没有理由不让在共享库中设置啊。所以这应该与是否是共享库关系不大。
猜测可能是符号与地址对应关系有误,如果你的本意为function1设置断点,结果gdb搞错了,设置一个毫不相干的地方,可能永远都不会执行到那里,这个断点自然没什么效果。
如果是这样,有两种方法可以解决:要么手动计算符号的地址,再设置断点,当然这样太累。另外就让gdb自动对应起来。经过反得尝试,用下列方法可以在共享库中设置断点,虽然有点麻烦,还是可行的。
1.         准备工作,编写下面几个文件:
test.c:
#include <stdlib.h>
int test(int a, int b)
{
    int s = a + b;
    printf(“%d/n”, s);
    return s;
}
main.c:
#include <stdlib.h>
extern int test(int a, int b);
int main(int argc, char* argv[])
{
    int s = test(10, 20);
    return s;
}
Makefile:
all: so main
so:
    gcc -g test.c -shared -o libtest.so
main:
    gcc -g main.c -L./ -ltest -o test.exe
clean:
rm -f *.exe *.so
(为了便于演示,整个过程在PC上测试,后来证实在实验板上能够正常工作)
2.         编译并设置环境变量
make
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
3.         运行gdbserver
gdbserver localhost:2000 ./test.exe
4.         运行gdb客户端
gdb
symbol-file test.exe
target remote localhost:2000
b main
c
5.         查看libtest.so的代码在内存中的位置。
(从gdbserver的输出或者用ps可以得到test.exe的进程ID,这里假设PID是11547)
cat /proc/11547/maps
输出:
00624000-0063e000 r-xp 00000000 03:01 718192     /lib/ld-2.3.5.so
0063e000-0063f000 r-xp 00019000 03:01 718192     /lib/ld-2.3.5.so
0063f000-00640000 rwxp 0001a000 03:01 718192     /lib/ld-2.3.5.so
00642000-00766000 r-xp 00000000 03:01 718193     /lib/libc-2.3.5.so
00766000-00768000 r-xp 00124000 03:01 718193     /lib/libc-2.3.5.so
00768000-0076a000 rwxp 00126000 03:01 718193     /lib/libc-2.3.5.so
0076a000-0076c000 rwxp 0076a000 00:00 0
00bbe000-00bbf000 r-xp 00bbe000 00:00 0
00fcc000-00fcd000 r-xp 00000000 03:01 1238761    /root/test/gdbservertest/libtest.so
00fcd000-00fce000 rwxp 00000000 03:01 1238761    /root/test/gdbservertest/libtest.so
08048000-08049000 r-xp 00000000 03:01 1238765    /root/test/gdbservertest/test.exe
08049000-0804a000 rw-p 00000000 03:01 1238765    /root/test/gdbservertest/test.exe
b7f8a000-b7f8b000 rw-p b7f8a000 00:00 0
b7f99000-b7f9a000 rw-p b7f99000 00:00 0
bfd85000-bfd9a000 rw-p bfd85000 00:00 0          [stack]
由此可以知道:libtest.so的代码在00fcc000-00fcd000之间。
6.         查看libtest.so的.text段在内存中的偏移位置:
objdump -h libtest.so |grep .text
输出:
9 .text         00000130 00000450 00000450 00000450 2**4
即偏移位置为0x00000450
7.         回到gdb窗口,加载libtest.so的符号表。
add-symbol-file libtest.so 0x00fcc450
(这里0x00fcc450 = 0x00fcc000 + 0x00000450)
8.         在共享库的函数中设置断点。
b test
9.         继续调试,可以发现在共享库中设置的断点,能够正常工作。

GDB调试器的使用

  默认情况下,gcc/g++编译的可执行文件是不包含调试信息的,GDB是一个源代码级的调试器,使用GDB调试程序需要程序的源代码、符号及其对应的行号等,其中符号和行号可以是单独的文件,亦可以在编译时嵌入到可执行文件中。使用gcc/g++时使用-g选项即可将必要的调试信息包含到可执行文件中,使用-g3选项还可以将源代码中的宏信息也包含进去。
另外,调试过程中需要随时查看源代码,但源代码并没有包含到可执行文件中。通常GDB在当前目录查找源文件,但某些情况下(比如调试系统命令)需要手动指明源代码的查找目录,directory ~向GDB指明到$HOME下查找源文件。
启动GDB的启动很灵活,它的各种特性,你可以在Shell下通过选项和参数指定,也可以在GDB启动之后在GDB自己的命令行下使用GDB内置的命令来指定。最常用的是直接使用命令gdb PROGRAM启动,这样gdb自动加载符号表等调试信息。若要向被调试程序传递参数,可以采用gdb –args program ARG1 ARG2的形式,其中–args(或者-args)是必须的,它告诉GDB该选项之后已经没有GDB需要的选项了。另外,还可以直接使用gdb启动,然后使用file program加载调试信息。此时若要设置被调试程序的参数,可以使用set命令的args子命令,如set args ARG1 ARG2. 还有一种传递参数的方法,在下面介绍。
断点调试程序,就是使用调试器(Debugger)通过检测和改变被调试程序(Debuggee)的状态、控制其执行的方式找出被调试程序中的错误和潜在的bug。调试程序,观察程序当前的行为的前提是让程序在“适当的时候”暂停运,那么什么是适当的时候呢?使用GDB时,让程序暂停运行需要使用断点。具体地,断点又可以分为普通断点(breakpoint以下简称断点),观察点(watchpoint),捕捉点(watchpoint)三类。
普通断点使用break命令(简写为b)设置。break命令的格式为break [bp-spec] [if CONDITION] [thread THREADNUM],bp-spec指明断点设置的位置,可以是行号、函数名或者指令地址,如果bp-spec省略,则断点被设置在程序所要执行的下一行代码(或者指令)上。if CONDITION指明当程序到达bp-spec位置时,只有CONDITION条件成立时程序才会暂停。thread THREADNUM用在多线程程序的调试中,断点只被设置在指定的线程号(GDB内部而不是系统使用的标号)为THREADNUM的线程上,如果THREADNUM为all则所有线程都会被设置断点。补充下bp-spec可以是函数名b FUNCTIONNAME(重载函数名需要使用”包含才能自动补全),可以是行号b LINENUMBER或者b FILENAME:LINENUMBER,还可以是指令地址b *ADDRESS。另外,break命令还有其它一些变种,比如tbreak设置临时断点,被使用一次就会自动删除,rbreak使用正则表达式来指明函数名。
观察点使用watch命令,命令格式与break相同,但它并不是指明断点的位置,而是指明一个表达式,每当该表达式的值改变时,程序便会被暂停。表达式可以是某个变量、由若干变量组成的表达式或者内存地址。
捕捉点是另一种断点,它使用某种事件的发生作为触发条件,命令各式为catch EVENT。这些事件主要包括异常的抛出和捕获(catch throw/catch)和某个系统调用(catch fork/open/exec, catch syscall CALLNUM)。
查看当前的断点设置情况可以使用breakpoints,也可以使用info breakpoints(或者简写为i b)命令,查看某个断点使用breakpoints bpnum,bpnum为断点号。
使用enable/disable bpnum使某个断点生效和失效,delete bpnum删除断点。bpnum还可以是一个范围,以此批量操作断点,比如d 2-6删除断点2到6。
使用ignore bpnum COUNT还可以使某个断点被或略COUNT次,即是说断点bpnum的前COUNT次到达都不会被触发,知道COUNT递减至0。另外,在COUNT递减至0之前,该断点上的条件是不会被考虑的。
CONDITION bpnum [if condition],修改bpnum上的触发条件,若if被省略,则bpnum断点上的条件将被删除。
运行

GDB启动和加载调试信息后,被调试程序并没有运行。使用run/r或者start命令,GDB建立子进程来运行被调试程序。run和start命令稍有不同,即run仅仅加载程序然后运行,而start会在程序的入口函数(main)设置一个临时断点,程序运行到那里就会暂停,临时断点也随即被清除。另外run和start命令后面都可以加上传递给被调试程序的参数,若不加参数则使用GDB启动时传递的参数或者使用set args命令设置的参数。若要清除参数而不退出GDB,使用不带参数的set args即可。
其它运行相关的命令还有

continue/c,继续运行。
next/n, 下一行,且不进入函数调用
stop/s, 下一行,但进入函数调用
ni或者si, 下一条指令,ni与si的区别同n与s的区别
finish/fini, 继续运行至当前栈帧/函数刚刚退出
until/u, 继续运行至某一行,在循环中时,u可以实现运行至循环刚刚退出,但这取决于循环的实现。

查看

调试的主要工作,我想就是检查程序的状态吧,内存的状态,程序的流程,指令的安排。GDB有多个命令来查看程序的状态,最常用的是list/l, print/p和x和disassemble。

list linenum/function列出第linenum行或者function所在行附近的10行,list *address列出地址address附近的10行。
list列出上一次list命令列出的代码后面的10行
list -,列出上一次list命令列出的代码前的10行
list列出的默认行数可由set listsize size来设置
p /fmt VARIABLE根据fmt指定的格式打印变量VARIABLE的值,常用的fmt有d(decimal), u(unsigned), x(hex), o(octal), c(character), f(float), s(string)
x /nfs ADDRESS是我最喜欢的命令,它显示ADDRESS地址开始的内容,形式由nfs指定。其中n为次数(个数),f是格式,除p命令可以使用的格式外,还可以使用i(instruction)打印指令,s为所打印内容的大小,可以是b(byte), h(half word), w(word, 4bytes), g(8bytes). nfs均可省略,若省略则使用最近一次使用x命令时的值,最初nfs是1dw。
disassemble /[r][m] [ADDRESS]将ADDRESS所在函数进行反汇编,ADDRESS也可以是一个由行号组成的区间。不指定任何选项时disas只简单的列出反汇编指令,指定m(mixed)选项时会对应地列出指令和源代码,指定r(raw)时会打印出指令对应的十六进制编码。

退出

Ctrl-C会终止当前调试的程序(而不是调试器)。q(quit)退出GDB,若退出时被调试程序尚未结束,GDB会提示,请求确认。
其它
help

使用GDB的过程中,如果对某一个命令的用法不清楚,可以随时使用help/h寻求帮助。
info

info/i命令也是一个十分常用的GDB命令,可以查看许多信息。

i program查看被调试程序的运行状态,如进程号、ip(指令指针)、是否运行、停止原因等。
i b [bpnum]查看断点
i f [frame-num]查看当前(或指定)栈帧,i f all还会列出当前栈帧的局部变量
i line LINENUM查看代码行LINENUM,打印其指令地址,此命令后执行x/i可查看该地址处的指令,然后回车即可继续向后查看接下来的指令
i reg查看寄存器状态,i all-reg查看包含浮点堆栈寄存器在内的所有寄存器情况
i args查看当前栈帧的参数
i s追踪栈帧信息,相当于backtrace/bt命令
i threads查看当前进程的线程信息

回到过去

跟踪调试程序的过程中,偶尔会错过一些关键点,不得不重新启动程序。如果错过的这些关键点不容易再现,就更令人懊恼了。GDB提供一种机制可以让你将程序向后调整,重新来过。这种机制叫做checkpoint,你可以在程序运行的关键点处执行checkpoint命令,你将得到一个数字(check-num)来标识这个checkpoint。在以后的某个时刻使用restart check-num将程序回滚到设置该checkpoint的时刻,而此时此刻的“内存状态”恰如彼时彼刻,你可以重新调试这段程序(比如设置不同的变量值来测试不同的情况)。但覆水难收的道理你是懂得,回滚的这段程序之间产生的内存之外的效应是无法恢复的,比如写出到文件的数据收不回来了(但文件的指针偏移是可以恢复的,因为它的值保存在内存),通过网络发出的数据就更要不回来了。
使用i checkpoints可以查看checkpoint信息,比如check-num及其所处代码行。
据我揣测,GDB的这种“回到过去”的伎俩并不是逐步撤销之前运行的指令,而是在checkpoint命令执行的时候,把被调试程序fork/clone了。
多线程

调试多线程程序与普通程序没有太大的区别。

i threads查看当前进程包含的线程的信息,包括线程号及其GDB内部标识号,当前处于前端的线程。
thread thread-num切换到线程thread-num
set scheduler-locking [on|off|step],这是一个比较重要的选项,它控制这当前调试线程与其它线程的执行关系。设置为on时,其它线程不会抢占当前线程。设置为off(默认)时,当前线程执行时随时可能被其它线程抢占。设置为step时,在执行step命令时不会被抢占,但使用next跳过函数调用时可以/可能会被抢占,即调度器会被执行。

技巧

回车。在GDB命令行下,简单的回车会执行上一个命令。而且GDB命令中可以使用回车重复执行的都是有记忆的,如果使用回车,该命令就会根据上一次的执行适当地调整参数重复执行。比如使用l func列出函数func附近的10行代码,接着回车就会打印接下来的10行。使用x/16xw ADDRESS以16进制形式查看ADDRESS处的16个字,接着回车就会以同样的格式打印接下来的16个字。如果你已经set $i=0了,那么通过p a[$i++]然后一直回车就可以依次打印数组a的元素了。x/i $eip打印下一条指令,接着回车就会打印下下一条指令,以此类推。但,有的指令是无法使用回车来重复执行的,比如run/start,总之,通常,你觉得不能/不适合重复执行的命令就无法重复执行。
命令简写,有的命令名称较长甚至很长,但GDB允许用户只使用足以区别其它命令的前几个字符来执行命令,当然你也可以使用TAB自动补全。另外一些极为常用的命令有专门的简写形式,通常只有一个字母,例如break/b, list/l, info/i, continue/c, next/n, step/s, nexti/ni, stepi/si, frame/f, print/p等等等等。
在GDB中可以自定义变量(仅供GDB内部使用),很多时候可以方便查看一些表达式的值。有的时候使用变量似乎是必须的,比如x *($esp)是不合法的,因为GDB不允许对寄存器变量进行解引用(dereference, but why?)。这时,设置变量set $p=*($esp),然后x $p就可以了。

这只是一个小小的不完全的总结,如果你从未使用过GDB,推荐使用RMS的《Debugging with GDB》学习,还有一本小书《GDB Pocket Reference》,不妨做你的调试菜谱,如果你喜欢GDB的话。

GDB全解

<1>.GDB调试教程

用GDB调试程序(一)

用GDB调试程序(二)

用GDB调试程序(三)

用GDB调试程序(四)

用GDB调试程序(五)

用GDB调试程序(六)

用GDB调试程序(七)

<2>. 定制ARM上的GDB调试器

http://hi.baidu.com/dos2004/item/ceec49a21da256db5af191cf

arm-linux-gdb+gdbserver环境搭建以及远程调试

————————————————

gdbserver远程调试是在嵌入式LINUX上调试应用程序的优秀手段之一,熟悉PC LINUX上GDB调试的人肯定非常乐于使用此种调试方法。至于GDB调试的优越性,非此篇的话题,于此不表。
gdb源码下载:http://ftp.gnu.org/gnu/gdb/
我的环境:gcc : 3.4.2
arm-linux-gcc : 3.4.1
下载GDB源码: 6.6
nfs共享目录: ~/tftpboot
主机IP:192.168.1.200   板子IP:192.168.1.168

1.编译arm-linux-gdb
$cd gdb-6.6
$./configure --target=arm-linux --prefix=/usr/local/arm/gdb -v
target指明编译生成的GDB用于调试ARM-LINUX程序,prefix指明安装目录
$make
#make install
#vi /etc/profile
export PATH=$PATH:/usr/local/arm/gdb/bin    --把arm-linux-gdb加入环境变量

2.编译gdbserver
$cd gdb/gdbserver
$
./configure --target=arm-linux --host=arm-linux
target含义同前,host指明编译生成的gdbserver运行在arm-linux上,前者没有设定host的原因是
arm-linux-gdb是在pc linux上运行的,就像arm-linux-gcc (很好理解的:))
$
make CC=/usr/local/arm/3.4.1/bin/arm-linux-gcc
其实这里也可以make CC=arm-linux-gcc,因为有的系统这要可能不行,我的是行的.
$cp gdbserver ~/tftpboot
~/tftpboot是我的NFS共享目录,目的是要把gdbserver下载到板子上

3.拷贝libthread库(如果运行gdbserver出错的话)
$cd /usr/local/arm/3.4.1/arm-linux/lib
$cp libthread_db-1.0.so ~/tftpboot

4.下载gdbserver到板子上,启动minicom
#mount -t nfs -o wsize=256,rsize=256 192.168.1.200:/home/lua/tftpboot /mnt/nfs
#cd /mnt/nfs
#cp gdbserver /usr/bin/
#cp libthread_db-1.0.so /lib/
#ln -s /lib/libthread_db-1.0.so /lib/libthread_db.so.1
#ln -s /lib/libthread_db-1.0.so /lib/libthread_db.so
就此准备工作做好了,*_*

5.调试示例
1 #include<stdio.h>
2
3 int main()
4 {
5     char *ptr = “csdn”;
6     printf(“%c\n”,*(ptr++));
7     return 0;
8 }
上面这段代码记为test.c,用arm-linux-gcc -g test.c -o test编译,再把生成的test文件复制到~/tftpboot
minicom下:
#cd /mnt/nfs
#gdbserver 192.168.1.200:7777 test
Process test created; pid = 842
Listening on port 7777

主机shell下
$cd ~/tftpboot
$arm-linux-gdb test
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-linux”…
(gdb)
注意一下显示信息的最后–host=i686-pc-linux-gnu –target=arm-linux,明白了吧。。。
target remote 192.168.1.168:7777   –连接gdbserver
Remote debugging using 192.168.1.168:7777
0x40000dd0 in _start () from /lib/ld-linux.so.2
表示连接上了服务器,:),接下来就可以调试了。arm-linux-gdb和GDB的用法一样,只是没有r这个命
令,运行程序用c命令。
(gdb) l
1       #include<stdio.h>
2
3       int main()
4       {
5               char *ptr = “csdn”;
6               printf(“%c\n”,*(ptr++));
7               return 0;
8       }
(gdb) b 3
Breakpoint 1 at 0x83d0: file test.c, line 3.

另外由于程序是在目标板上运行,调试是在PC下,程序的结果还是会在目标板上显示的,
例如:minicom,lcd等。
btw,附近一篇介绍GDB使用的文章:http://blog.csdn.net/haoel/archive/2003/07.aspx,这下全了吧。哈