2015年(14)
分类: C/C++
2015-07-03 13:56:35
以调试模拟器中的native library code为例。
Host: ubuntu
Target: Android ICS
1.将gdbserver放入设备。
确保系统有arm-*-gdb,及存在设备端将要运行的gdbserver,gdbserver可以由google ndk中获取,在ndk的如下目录可以找到这个文件:
点击(此处)折叠或打开
然后,通过adb shell进入设备,在/data下创建bin 目录:
点击(此处)折叠或打开
再通过adb push命令将gdbserver 放入设备:
点击(此处)折叠或打开
2、在设备端启动gdbserver并attach到所要debug的进程
点击(此处)折叠或打开
gdbserver 后面跟的第一个参数为端口号,之后的--atach 为gdbserver的选项,之后的数字为所要调试的进程的PID。
3、在Host端启动arm-*-gdb
网上有高手build的各种交叉编译工具链来方便大家的嵌入式开发,单这个工具链中的gdb命令实际文件名称的前缀和后缀都会是相同的,中间的那个*可以见到各种各样的形式,比如linux,linux-androideabi,none-linux-gnueabi等等。
点击(此处)折叠或打开
点击(此处)折叠或打开
同时,在设备端也可以看到有如下的输出,来显示着这server端与client端难以协调的步调:
点击(此处)折叠或打开
出现这样的状况,是由于gdbserver和arm-*-gdb版本不对应所致。由上面我们启动arm-linux-androideabi-gdb时的输出可以看到,其版本为GNU gdb 6.6。在设备上,我们可以查看gdbserver的版本信息:
点击(此处)折叠或打开
我们可以换用和gdbserver版本较为接近的arm-*-gdb。此时在host端所需输入的命令及相应的输出如下:
点击(此处)折叠或打开
点击(此处)折叠或打开
这即是表明,gdb client端和server端有成功的链接。
接下来通过file命令来加载将要调试的可执行文件,对于android application来说,均为 out/target/product/generic/symbols/system/bin/app_process 这个文件,及设置搜索solib的搜索路径。
点击(此处)折叠或打开
点击(此处)折叠或打开
gdb常用调试命令
0、查看程序源代码
directory(dir) DIR
Add directory DIR to beginning of search path for source files.Forget cached info on1、程序运行时参数。
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。
2、运行环境。
path
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
pwd 显示当前的所在目录。
4、程序的输入输出
info terminal 显示你程序用到的终端的模式。
使用重定向控制程序输出。如:run > outfile
tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb
5、设置断点(BreakPoint)
我们用break命令来设置断点。正面有几点设置断点的方法:
break
在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。
break
break +offset
break -offset
在当前行号的前面或后面的offset行停住。offiset为自然数。
break filename:linenum 在特定源文件filename的特定行linenum处设置断点。
break filename:function 在源文件filename的function函数的入口处停住。
break *address 在程序运行的内存地址处停住。
break break命令没有参数时,表示在下一条指令处停住。
break ... if
...可以是上述的参数,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
rwatch
awatch
info watchpoints 列出当前所设置了的所有观察点。
7、设置捕捉点(CatchPoint)
可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
catch
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
7、unload 或 unload
tcatch
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
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