NDK自带gdb夸平台调试

GDBServer位置在:
/opt/android-ndk-r9d/prebuilt/android-arm/gdbserver/gdbserver

GDB的位置在:
/opt/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb


1.2:代码编译和准备:
Android NDK 这套系统,已经准备好调试Native C程序所需要的一切。
1.2.1: 以Debug模式编译:
首先,在Application.mk中作如下修改:
APP_OPTIM := debug

APP_CFLAG:=-g -ggdb -O0

1.2.2:得到Debug版本程序:
在obj/local/armeabi-v7a/目录下,找到库文件和可执行文件。并push到目标平台。
不能使用libs/armeabi-v7a/目录下的版本。因为这里的版本是strip 过的。debug信息被去掉了。

2. Debug环境建立
2.1:环境介绍:
目标平台为ARM-Cortex-A9. 
IP地址:10.0.0.13

编译和调试机为:X86-64bit Linux. Fedora 18.
IP地址为:10.0.0.2

目标平台上:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
./gdbserver 10.0.0.2:1234 V4L2_Utils
这句话涵义是:Debug V4L2_Utils这个程序,未来的调试方为:10.0.0.2,端口为1234

Process V4L2_Utils created; pid = 816
Listening on port 1234

显式V4L2_Utils 进程已经创建,并且监听1234端口。

调试机上:
/opt/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb V4L2_Utils
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
...
Reading symbols from /home/sam/work/current/svn/Camera_Utils/private/src/obj/local/armeabi-v7a/V4L2_Utils...done.
(gdb) 

这里说明读取符号正常。

(gdb)  target remote 10.0.0.13:1234
说明远端是10.0.0.13. 端口为1234.

本地显示:
Remote debugging using 10.0.0.13:1234
warning: Unable to find dynamic linker breakpoint function.
GDB will retry eventurally.  Meanwhile, it is likely
that GDB is unable to debug shared library initializers
or resolve pending breakpoints after dlopen().
0x2ab5f220 in ?? ()
(gdb) 

目标平台显示:
Remote debugging from host 10.0.0.2

说明连接成功。之后就可以在调试平台使用了.

3. Debug 常用命令: 
List: 列出代码: 
(gdb) l
print 出代码。
list
显示程序第linenum行的周围的源程序。

list
显示函数名为function的函数的源程序。

list
显示当前行后面的源程序。

list -
显示当前行前面的源程序。


list ,
显示从first行到last行之间的源代码。

list ,
显示从当前行到last行之间的源代码。

list +
往后显示源代码。

list filename:linenum
哪个文件的哪一行

list  filename:function
哪个文件中的哪个函数。

list *address   
程序运行时的语句在内存中的地址。


(gdb) b 139   
在139行设置断点。

在不同文件设置断点。
(gdb) break filename:line-number 
(gdb) break filename:function-name \

对某Class的成员函数设置断点
(gdb) b className::functionName


(gdb) c
开始调试(不能用r, 因为远端已经开始了)

(gdb) p arv
察看arv的值。
/x  按十六进制格式显示变量
/d  按十进制格式显示变量
/u  按十六进制格式显示无符号整型
/o  按八进制格式显示变量
/t  按二进制格式显示变量
/a  按十六进制格式显示变量
/c  按字符格式显示变量
/f  按浮点数格式显示变量


察看结构体内容:
IplImage *m_pResDisplayImgPtr
(gdb) p m_pResDisplayImgPtr
(gdb) p m_pResDisplayImgPtr
$1 = (IplImage *) 0xe39220
(gdb) p *m_pResDisplayImgPtr
$2 = {nSize = 112, ID = 0, nChannels = 3

如果想要格式更好:
(gdb) set  print  pretty on
(gdb) p *m_pResDisplayImgPtr
$3 = {
  nSize = 112, 
  ID = 0, 
  nChannels = 3, 
  alphaChannel = 0
}


(gdb) step
单步执行。


4. 调试动态链接库
关于调试动态库,先谈谈Sam自己以为的原理:
当编译选项中包含: -g  -O0时,目标文件中包含调试信息。 可执行程序,动态库均包含各自的调试信息。
在调试端,使用gdb ip:port App  时,应用程序APP的调试信息被载入。
但当我们想要调试到动态库so 内部时,需要有两个条件。
1. so内有调试信息。这就要求制作so 时 有 -g -O0.  同时没有被 strip 过。
2. 让gdb知道这个动态库放在什么地方。 这就要求告知gdb 在哪找目标动态库。

在gdb下,可以查询和设置 动态库搜索路径:
(gdb) show solib-search-path
(gdb) set solib-search-path   ../../../../../../V4L2Lib/private/src/V4L2Lib/obj/local/armeabi-v7a/

告知GDB在指定目录寻找库文件。

此时,在想要调试的库函数上设置断点。再单步调试,就可以进入库中调试了。


















你可能感兴趣的:(Linux下基本编译汇总)