debugs on android

125 篇文章 0 订阅

http://foreveryoung001.iteye.com/blog/1538077

http://bbs.csdn.net/topics/390021045

书:Debug Hacks中文版:深入调试的技术和工具,软件调试:Software Debugging,编译原理(第2版) 

android的编译系统: 
按配制(一个product或某个特定的配制)去收集所有的Android.mk,然后解析这些Android.mk,然后生成相应的make脚本文件或相应的数据结构,然后make. 
(end) 

要想在有源码工程的Android上单步调试编译出来的so或可执行程序(c),至少应关闭所有的优化(如,防止内联函数内联),并且在编译时加上-g选项(生成调试信息): 
1. 将相应模块的Android.mk中的: 
*_CFLAGS或CFLAGS的值中的-ON改为-g -O0 // 注意,这将关闭gcc的优化,从而使得编出来的程序大小可能大幅变大,而且可能大幅增加编译时间。最终的结果是导致编出的程序运行速度非常之慢,这时就要求用真机或高配电脑(如果是跑在模拟器上的话)进行调试。 
2. 重新编译这些模块,然后按下文中相应方式进行调试。 

附:gcc的优化等级: 
gcc默认提供了5级优 化选项的集合: 
-O0:无优化(默认) 
-O和-O1:使用能减少目标文 件 大小以及执行时间并且不会使编译时间明显增加的优化.在编译大型程序的时候会显著增加编译时内存的使用. 
-O2: 包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化.编译器不执行循环展开以及函数内联.此选项将增加编译时间和目标文件的执行性 能. 
-Os:专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项.并且执行专门减小目标文件大小的优化选项. 
-O3: 打开所有-O2的优化选项并且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize优化选项. 
(end) 

1. 调试自己开发的应用(ndk)和sdk app(含jni)中的c/c++(so文件) 
见下文:调试sdk app(含jni)中的c/c++(so文件): 
2. 调试原生应用(带jni)中的so的源码(c/c++): 
找到对应的id,启动gdbserver并监听之,客户端的可执行程序为app_process(对应任何一个/system/app中的apk<限原生的应用,自己开发的应用见上面第1点>)。 
3. 调试android中的可执行文件如:mediaserver,即调试/system/bin中的程序: 
见下文:我的调试(android 2.3.7:full-eng , 模拟器,调试rild,eclipse): 
(end) 

我的调试(android 2.3.7:full-eng , 模拟器,调试rild,eclipse): 
服务端配置: 
adb -s emulator-5554 forward tcp:5039 tcp:5039 
# gdbserver :5039 --attach 32 // adb shell中, 32是rild的进程号,可用ps查看 
上面已启动了服务端,下面配置和启动客户端: 

客户端: 
新建一个C或c++的工程(只作代码查看器)名为ril_debug_demo: 
将and2.3.7/hardware/ril/rild中的所有文件拷到新建的工程的src目录下 
右击ril_debug_demo选debug as进入configures: 
选择C/C++ Application,新建一个调试配置条目ril. 
在右侧最下面的 process launcher  select other 选择standard ... 
然后在main选项卡下的C/C++ Application处填写为/home/and2.3.7/out/target/product/generic/symbols/system/bin/rild,这个文件必须是带符号表的(而不是/home/and2.3.7/out/target/product/generic/system/bin/rild) 
然后将“Project”选刚建的工程名:ril_debug_demo 
然后到Debugger选项卡,Stop on startup at可根据需求配,这里就没有配。 
Gdb debugger 为:$ndk_home中的(android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb)或者是:/home/and2.3.7/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb,注意版本须对应(find prebuilt -name arm-eabi-gdb然后选最新版即可)。 
Gdb command file为任一文件(用来配置arm-eabi-gdb的),该文件内容如下: 
file /home/and2.3.7/out/target/product/generic/system/bin/rild 
set solib-absolute-prefix /home/and2.3.7/out/target/product/generic/symbols/system/lib 
set solib-search-path /home/and2.3.7/out/target/product/generic/symbols/system/lib 
底下的Verbose console mode 一定要记得勾上,这样才能在eclipse控制台中用指令来与gdb交互。 
在connection子项中,设type为tcp,端口为5039 
点击debug即可切换到debug视图,你再到工程中的ril.c中设断点,就会成功了。 

注意,调试的目标设备中的程序一定要与源码工程中的源码相对应,而且设备中的android system.img最好是eng版的,否则,设备中的程序已经过了优化,与源码不一定对得上。 

如果编译系统后没有/home/and2.3.7/out/target/product/generic/symbols/文件夹,则说明编译的不是debugable版本,如果需要编译某一模块的debuggable版本,无需重新编译整个系统,可在/home/and2.3.7/buildspec.mk中配制以使在编译该模块时将其编译成带符号表的版本。配制示例: 
DEBUG_MODULE_lidvm:=true  # 虚拟机模块设为debug 
TARGET_CUSTOM_DEBUG_CFLAGS:=-O0 -mlong-calls 
(end) 


对调试的感性认识: 
1. 调试:调试也是一个程序,它有流程,这个流程就是被调试程序所运行的环,也即,被调试程序是跑在调试器程序的框架之中的。调试的目标是:将源码与目标的执行流相匹配并对执行流加以控制 
2. 客户端调试进程 -> 调试配制信息(源码,源码编译后得到的可执行文件或库(将被安装到设备上运行)) <- 服务端调试进程 <- 目标执行程序(执行流,已安装并运行的程序或库) 
(end) 

用gdb和gdbserver调试android native code 
http://www.4ucode.com/Study/Topic/1891789 
使用GDB调试Android NDK开发的程序 
http://www.android123.com.cn/topic/ndk/962.html 
使用gdb在Android Emulator中进行调试 
http://android.tgbus.com/Android/tutorial/200901/174638.shtml 
使用GDB 单步调试Android本地代码 
http://www.bobbog.com/archives/24 
Android上如何用arm-eabi-gdb调试程序 
http://pjq.me/wiki/doku.php?id=android:gdb-debug 
Android系统中调试动态链接库so文件的步骤 
http://blog.wjmjimmie.cn/archives/154.html 
GDB调试webkit技巧一则 
http://mogoweb.net/archives/309 
用gdb调试 android webkit  
http://blog.csdn.net/mayqlzu/article/details/5669241 
用Eclipse开发与调试纯粹的Android C++程序,非ndk-build、ndk-gdb 
http://www.eye88.com/463 
使用gdb在Android Emulator中进行调试c程序 
http://xiangmocheng.blogbus.com/logs/41014988.html 
android-gdb-6.8.tar.bz2 
http://117.79.157.233/download/happyfirst_2009/4004971 
用GDB调试Segmentation Fault错误  
http://blog.csdn.net/learnhard/article/details/4879834 
自己编译Android gdbserver(解决运行 gdbserver时 Segmentation fault 问题)  
http://blog.csdn.net/yuleslie/article/details/7226767 
用GDB调试Segmentation Fault错误  
http://blog.csdn.net/learnhard/article/details/4879834 
自己编译Android gdbserver(解决运行 gdbserver时 Segmentation fault 问题)  
http://blog.csdn.net/yuleslie/article/details/7226767 
Android build gdbserver  
http://blog.csdn.net/yuleslie/article/details/7226605 
Linux使用日志系统调试守护进程 
http://www.jz123.cn/text/0532676.html 
守护进程怎样调试? 
http://topic.csdn.net/t/20060714/21/4881641.html 
gdb多线程/多进程(守护进程)调试  
http://blog.csdn.net/yeahguyewen/article/details/6196190 
Linux如何避免进程僵死 
http://www.jz123.cn/text/0532677.html 
详解:linux daemon守护进程  
http://www.xker.com/page/e2011/0923/102718.html 
(end) 

调试LINUX驱动的方法 
1.通过printk消息 
2.通过#DEBUG预处理 
3.通过/proc系统 
4.通过ioctl系统调用 
5.通过strace命令 
(end) 


-------------------------------------------------------------------- 
http://hi.baidu.com/libra1588/blog/item/da2f3df7122c6d36720eecc4.html/cmtid/41c865dab58ce6d4b6fd4807 
交叉调试时arm-linux-gdb提示:No symbol table is loaded. Use the "file" command. 
2011年03月14日 星期一 下午 3:27 
今天在Linux上用GDB进行程序调试的时候,发现提示:No symbol table is loaded.  Use the "file" command. 

导致这个错误的原因一般是:在交叉编译时没有加-g选项. 

所以在编译程序时一定要注意加上-g这个选项,尤其在写Makefile文件时, 

一定不要偷懒,仔细检查,确认每个编译条件都添加了-g选项。 
(end) 
-------------------------------------------------------------------- 
调试本地C程序(运行在ubuntu上的可执行文件): 
eclipse -> new project -> c -> project type: hello world... ; project name: xxx -> finish 
此时创建有src和includes(文件系统中实际只有src). build后有:src,includes,debug和binaries(文件系统中实际只有src和Debug). 
若要看看这些目录的功能区别,看.project和.cproject两个配制文件。 
(end) 

-------------------------------------------------------------------- 
调试frameworks(含jni)中的底层c/c++(so文件): 
http://mysuperbaby.iteye.com/blog/939477 
android中c/c++程序的调试(eclipse) 

1.          使用gdbserver调试 
使用JDWP只能调试java层面的程序,如果想调试C层面的代码,需要使用gdbserver方式,gdbserver的服务端和客户端都包含在android的源码中。 
server端是out/target/product/xxxxxx/system/bin/gdbserver。 
client端是prebuild/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb),不需另外安装。 
(请看完本文再开始调试,尤其是“注意”部分) 
本文依据张博的调试文档, 加以扩充说明,感谢原创者。 
2.          调试前的准备:编译DEBUG版本的程序和库 
1)         新建(或修改)ANDROID源码根目录的buildspec.mk,加入以下内容 
DEBUG_MODULE_lidvm:=true  # 虚拟机模块设为debug 
TARGET_CUSTOM_DEBUG_CFLAGS:=-O0 -mlong-calls 
(请修改具体模块名,我调试的是虚拟机的libdvm.so库) 
2)        重编dalvik模块 
$ make clean-libdvm 
$ make dalvik snod 
3)         重烧system.img或替换手机中的相应模块 
3.          gdb server端配置 
1)         端口映射 
$ adb forward tcp:5039 tcp:5039            把设备的5039端口映射到PC的5039 
设定之后用netstat -na命令可看到PC的5039端口已处于listen状态 
注意每次断开手机再连接时,都要重新执行该命令 
2)         调试进程号为2014进程 
$ adb shell 
# ps 找进程号 
# gdbserver :5039 --attach 2014    # 指明tcp端口号和进程号 
注意:用此方法只适用于对已运行的程序debug(不能使用直接在gdbserver后跟程序名的方式运行) 
此时2014进程被挂起,等待调试 
4.          gdb client端配置 
1)         用命令行工具调试 
$ $ANDROID_DIR/prebuilt/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb $ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process 
注意可执行程序名必须是app_process,不是你所调试的程序名 
(gdb) set solib-absolute-prefix $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/ 
(gdb) set solib-search-path $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/ 
以上路径为GDB默认库的搜索路径,即交叉编译器库路径,若不设定,则找不到符号表,(带符号表的库在symbols/system/lib/*,手机里strip后无符号表的库在system/lib/*,它们必须配套使用) 
(gdb) target remote :5039     指明TCP端口号 
此时连接gdb server,可设断点调试,按c继续执行程序 
2)         用eclipse调试 
a)          安装cdt,使eclipse支持c/c++程序的开发 
                                       i.              下载 
从http://www.eclipse.org/cdt/downloads.php下载cdt-master-4.0.0.zip 
                                      ii.              解压 
$ mkdir cdt; cd cdt; unzip ../cdt-master-4.0.0.zip 
                                    iii.              将解压缩后的features、plugins两个文件夹的内容复制到Eclipse安装目录中 
$ cp plugins/* ../../eclipse/plugins/ 
$ cp features/* ../../eclipse/features/ 
                                    iv.              重新开启Eclipse即可 
$ eclipse -clean 
在新建project中即可看到c/c++相关选项,说明已安装成功 
b)         加入要调试的代码 
                                       i.              新建C++ project (菜单File->New->Project…) 
不使用default location,把Location指定成代码所在目录 
                                      ii.              取消自动编译选项(菜单Project->Build Automatically) 
c)          配置gdb环境 
配置Debug Configurations(菜单Run->Debug Configurations…) 
                                       i.              新建一个C/C++ Local Application(在最新的cdt中如果没有这个名称,则就是“C/C++ Application”)的debug configuration 
                                      ii.              Main选项卡中 
指定Project为新建的C++工程, 
C/C++ Applications为: 
$ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process 
                                    iii.              Debugger选项卡中 
指定Debugger为gdbserver Debugger, 
Main子选项卡的Gdb debuger设为: 
$ANDROID_DIR/prebuilt/linux-x86/toolchain/xxxxxx/bin/arm-eabi-gdb 
GDB command file设为一个文件名,文件内容如下: 
file $ANDROID_DIR/out/target/product/xxxxxx/system/bin/app_process 
set solib-absolute-prefix $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/ 
set solib-search-path $ANDROID_SRC)/out/target/product/xxxxxx/symbols/system/lib/ 
Connection子选项卡(要出现这个选项卡你必须先点击最下面的 process launcher  select other 选择standard create...那一项,然后回到debugger后在顶部Debugger选:gdbserver!!!!!@!!!!@!!!!!! Connection子选项卡即出现了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ): 
Type设为TCP,Port number设为5039 
                                    iv.              点击Debug按钮进入调试,之前挂起的程序此时继续运行 
d)         设置断点及调试 
                                       i.              找开某一C程序(菜单->Open file) 
                                      ii.              在程序中双击可设置断点,设置后断点出现在右上的Breakpoints中 
                                    iii.              Debug选项卡提供了工具调试(suspend, resume等) 
5.          加打印语句 
如果需要在C程序中加打印语句,有两种方法 
1)         直接在代码中使用printf,此方法只能应用于从命令行启动程序的情况,运行时可以adb shell中看到打印信息 
2)         使用程序中提供的重定项后的打印语句,并在logcat中看到它 
例如在libdvm.so中使用dvmFprintf(stderr, “xieyan log\n”); 
6.          可能出现的问题及解决方法 
1)         在找不到原因时,可以写一个在android可以运行的简单c语言程序用gdbserver调试,以简化问题,android中c程序做法见: 
http://www.top-e.org/jiaoshi/html/?157.html 
2)         我的是在arm-eabi-2.4.1的编译器编出来的,你的可能不是,编译时用make showcommands 确定你的系统使用的编译工具链,否则如果你debug时用的和编译时用的版本不一致,会导致读符号表时出错(注意看提示) 
3)         有时编译会引起源码目录的变化,请在左侧Project explorer中刷新相关项目 
(转载请注明出处:http://xy0811.spaces.live.com) 

-------------------------------------------------------------------- 
调试sdk app(含jni)中的c/c++(so文件): 
http://www.cnblogs.com/shadox/archive/2011/12/02/2272564.html 
Eclipse+CDT+GDB调试android NDK程序 (原文带图) 
先介绍一下开发环境,在这个环境下,up主保证是没有问题的。 
ubuntu 11.10 
eclipse 3.7(indego) for java 
jdk 6 
android sdk 2.2 
andrid ndk r7 

当然,在windows环境下通过cygwin等工具也是可以实现gdb调试的,我也确实实现过。但是性能实在太低,卡的根本没法用。Linux下直接用gdb调试本地方法是很流畅的。 
再确定安装并配置好开发环境之后,就可以开始了。 
首先得确定自己能够正常的运行一个ndk工程,连运行都成问题的话,也就谈不上什么调试了。 

新建一个android项目,选择crete project form existing source,源代码位于 
/home/shaodx/android/android-ndk-r7/samples/hello-jni,即ndk目录的samples/hello-jni。 


Next> 
Sdk target 就选2.2吧 ,其他的虽然没测试,应该也没什么问题。 


Finsh 

Hellojni项目极其简单,看代码就懂了。在activitie下建立一个textview,然后调用一个natvie方法来返回一个字符串,然后把textview的text设置为这个字符串。 
为了方便看到调试后的效果和局部变量的变化情况,我加了几行对程序结果没影响的代码。 
Java代码: 

C++: 

当然,这个时候直接运行的话,程序肯定会崩溃的。因为动态链接库还没编译好。Ndk根目录下的ndk-build负责编译so文件。首先进入项目所在目录,然后运行ndk-build即可。 
效果如下: 

出错了….. 
Host 'awk' tool is outdated. 
上网搜索之后的解决方案如下: 
到/home/shaodx/android/android-ndk-r7/prebuilt/linux-x86/bin/目录下找到这个awk,file一下: 

这个awk文件居然是64位版的,难怪之前说过期了。(google程序员粗心了吧) 
解决方案居然是把这个awk删了就行了…………….. 
解决问题之后,换个姿势,再来一次 


So文件存在于libs/armeabi/libhello-jni.so。 
现在就可以运行程序了。 

不过要是每一次修改c++代码都还要调用ndk-build的话,那也太麻烦了。介绍一个一劳永逸的方法。 
首先,要给eclipse安装一个CDT,eclipse>help>install new software 
下载地址为   http://download.eclipse.org/tools/cdt/releases/indigo/ 

反正我是把所有的选项都给安装了,也花不了太多的时间。 
然后是安装sequoyah  地址为 http://download.eclipse.org/sequoyah/updates/2.0/ 
这个就只需要安装Sequoyah Android Native Code Support 一项就可以了。 

然后把当前项目转换为C++项目。 
File>new>other: 


Convert to a c/c++ Project 
依照图中所示设置: 

Finish。 
这个时候,项目中的c++代码也会被识别了。一般这个时候就会爆出一堆错误,主要是gcc找不到jni.h头文件,同样也识别不了来自jni的一些函数和数据类型: 


于是就要给gcc添加一个环境变量让它来找到jni.h了,环境变量名称为C_INCLUDE_PATH。这个名字不能乱写,windows下类似的环境变量叫做INCLUDE。linux修改环境变量有很多的方法,可以上网搜索一下。我习惯于修改用户目录下的.bashrc文件。 
着这个文件末尾加上 
set C_INCLUDE_PATH=.:XXXXXXXXX() 
export C_INCLUDE_PATH 
然后重新登录一下,这个环境变量就会生效了。 
Eclipse中还要设置一下对应的环境变量。 
然后多刷新几次工程,这些错误就消失了。 
接下来,进行C++代码的编译配置。 
进入工程属性页,build command设置为ndk下ndk-build的完整路径。 


将Behavior选项页下的build处的all替换为空格 


接下来就可以直接运行了,每次运行的时候,就会自动把C++代码编译成so文件。同时,可以在eclipse中编写java代码和C++代码,很是方便。 




往下的工作就真的跟调试相关了。 
首先进入工程目录,然后运行ndk目录下的ndk-gdb。执行这一步骤时,应当先确保有模拟器在运行。如果有人更习惯于命令式的方法来调试程序的话,就可以直接用这个ndk-gdb来调试程序了。接下来的步骤就是把这个gdb调试图形化。 


在eclipse下进入debug>debug configuration,选择C/C++ Application,main选项卡下的C/C++ Application处填写为/home/shaodx/android/android-ndk-r7/samples/hello-jni/obj/local/armeabi/app_process,这个文件是专为调试而存在的,假如发现找不到这个文件的话,就应当先运行一次ndk-gdb。只运行ndk-build是不会产生这个文件的。Project选择当前的HelloJni。 

最下面的 process launcher  select other 选择stadard ... 

然后进入Debugger选项卡,Stop on startup at 填写的是C++程序的入口函数,这个项目中就是Java_com_example_hellojni_HelloJni_stringFromJNI了,我觉得这个参数应该没什么用的,记得设置断点就行了。Gdb debugger 为:home/shaodx/android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb,这个路径下有很多文件针对其他平台的,别选错了。Gdb command file为/home/shaodx/android/android-ndk-r7/samples/hello-jni/obj/local/armeabi/gdb2.setup,目前这个gdb2.setup文件还不存在,待会在创建。底下的Verbose console mode 一定要记得勾上,这样才能在eclipse控制台中用指令来与gdb交互。 



进入debugger options的 connection子项,type为tcp,端口为5039: 


设置完毕之后,apply。 
接下来只需要修改两个文件即可。修改之前记得备份 
首先是ndk-gdb,把最底下的一行 “$GDBCLIENT -x `native_path $GDBSETUP`”直接去掉,保存。 


然后把'/home/shaodx/android/android-ndk-r7/samples/hello-jni/obj/local/armeabi'目录下的gdb.setup复制一份,命名为gdb2.setup。把gdb2.setup打开,去掉最后一行的“target remote :5039”,千万不要在以为把gdb.setup修改好,然后把之前的设置指向gdb.setup会起作用,因为每次调用ndk-gdb的时候,都会产生一个新的gdb.setup 来覆盖掉修改。 


然后就可以给代码设置断点了,首先在调用本地方法之前记得有一个断点,之后也设置一个。 


C++的代码在函数入口处设置一个断点即可。 
下面开始正式的调试了,先运行项目的java调试。程序会再运行到第一个断点处停下来。 
这个时候赶紧运行在命令行下进入工程目录,然后运行ndk根目录下的ndk-gdb。 
运行之后是没有任何输出的。 


然后启动C++的debug,即之前配置好的那个jni debug。 
如图: 


由于在C++程序之也设置了断点,继续摁F6就可以直接执行到C++程序中。 
来个大图,熟悉eclipse的调试就没什么压力了。右上角可以直接看到局部变量的值,包括传进来的参数。 


同时,可以在控制台直接与gdb通讯,要退出C++程序的调试的话,continue即可,程序又回到java代码: 




完毕。 

-------------------------------------------------------------------- 
调试/system/bin中的可执行c程序: 
http://blog.sina.com.cn/s/blog_923f19060100zuvt.html 
用GDB调试Android中C/C++程序(命令行) (2012-02-13 19:17:08) 
标签: android 程序 杂谈
一、编译Android gdbserver(非必须) 
        因手头Android 2.3源码编译后的版本执行gdbserver时报错:Segmentation fault,不得不重新编译gdbserver。 

1、编译gdbserver 
编译过程参考博文:自己编译Android gdbserver(http://blog.csdn.net/yuleslie/article/details/7226767,解决运行 gdbserver时 Segmentation fault 问题)。 

2、使用新编译的gdbserver替换原有版本gdbserver 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb push ~/gdb_build/install/gdbserver /system/bin 

二、使用带调试符号表的C/C++程序替换原有程序 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb push out/target/product/xxxx/symbols/system/bin/debug_demo /system/bin 

三、使用gdbserver调试android C/C++程序 
1、调试端口映射,把设备的5039端口映射到PC的5039 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb forward tcp:5039 tcp:5039 
设定之后用netstat -na命令可看到PC的5039端口已处于listen状态 
simba@simba-Vostro-3400:~/neptune/android_2.3$ netstat -na | grep 5039 
tcp        0      0 127.0.0.1:5039          0.0.0.0:*               LISTEN     

2、gdbserver attach被调试程序 
adb shell中执行被调试的程序,ps命令查看其PID并gdbserver attach 
方法一: 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb shell gdbserver :5039 /system/bin/debug_demo & 
[3] 17600 
simba@simba-Vostro-3400:~/neptune/android_2.3$ Process /system/bin/debug_demo created; pid = 3323 
Listening on port 5039 

方法二: 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb shell /system/bin/debug_demo & 
[3] 22614 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb shell ps | grep /system/bin/debug_demo 
root      3353  3352  1048   412   800cc220 6fd0bdac S /system/bin/debug_demo 
simba@simba-Vostro-3400:~/neptune/android_2.3$ adb shell gdbserver :5039 --attach 3353 & 
[4] 26856 
simba@simba-Vostro-3400:~/neptune/android_2.3$ Attached; pid = 3353 
Listening on port 5039 

3、gdb客户端命令行调试 
simba@simba-Vostro-3400:~/neptune/android_2.3$  /home/simba/neptune/android_2.3/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gdb ./out/target/product/neptune_youngmanlotus/symbols/system/bin/debug_demo 

(gdb) set solib-absolute-prefix ./out/target/product/neptune_youngmanlotus/symbols/system/bin/ 
(gdb) set solib-search-path ./out/target/product/neptune_youngmanlotus/symbols/system/bin 

这里的gdb的版本一定要正确。这时已经进入了gdb调试模式,还需要进行与远程的gdbserver进行连接,在gdb模式下输入: 
(gdb) target remote :5039 

4.开始愉悦的调试吧 


-------------------------------------------------------------------- 
调试ndk app: 

-------------------------------------------------------------------- 
Android C/C++层打开LOG并添加日志: 
http://hi.baidu.com/mcu99/blog/item/306a0b2ab9b29938d52af1f2.html 

在Android C/C++层添加LOG调试(LOGI\LOGD\LOGE...)输出支持 
2011-04-02 11:47 
最近在研究Android 2.3.3源代码的C/C++层,需要对代码进行一些调试,但是奇怪的是,直接添加LOGD("XXXXXXXX");,使用logcat却看不到任何输出,换成LOGI、LOGV、LOGW、LOGE也没有效果。于是在网上查找解决方法,经过几次试验,终于找到了,现在贴到下面备忘: 

第一步:在对应的mk文件中加入:LOCAL_LDLIBS := -llog 
第二步:在要使用LOG的cpp文件中加入: 
#include <android/log.h> 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "keymatch", __VA_ARGS__) 
第三步:这样就可以使用了:LOGD("我要看到的调试信息^_^"); 

这样,在logcat端看到的输出是: 
D/keymatch( 32):我要看到的调试信息^_^ 

如果想改变输出中的各项内容,可以参考相应颜色的标示,比如,如果想定义LOGE,就可以把上面的ANDROID_LOG_DEBUG改成ANDROID_LOG_ERROR,同理,LOGI神马的也都以此类推: 
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "ProjectName", __VA_ARGS__) 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "ProjectName", __VA_ARGS__) 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO  , "ProjectName", __VA_ARGS__) 
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN  , "ProjectName", __VA_ARGS__) 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "ProjectName", __VA_ARGS__) 

当然,如果不嫌麻烦,也可以直接使用__android_log_print函数,而不define定义LOGxxx 

如果还想了解更详细的内容,也可以参考这篇文章: 《在android 输出log 信息 用于调试》 

另外,有文章称此方法在编译动态库的时候可能会出问题,会提示cannot find -llog的错误。意思是找不到liblog.so这个库文件。 
因此需要改成 LOCAL_LDLIBS:=  -L$(SYSROOT)/usr/lib -llog 才可以正常编译。但是我这边编译动态库的时候,好像不用这样改也行,没发现编译时提示“cannot find -llog”的错误。如果您在实践过程中发现有这样的问题,可以参考该文章,链接在此:《如何在android native编程中使用logCat》 
(end) 


http://www.4ucode.com/Study/Topic/1891789 

我仅给出自己用gdb和gdbserver调试android native code的实际过程,希望对大家有用。 

      注:以调试mediaserver进程为例. 

      第一步:你需要下载android,以debug方式编译,并以生成的image起模拟器或者设备。 

      第二步:你需要从“http://developer.download.nvidia.com/tegra/files/tegra-gdb-20100430.zip”下载一个gdb,覆盖到android源码中gdb对应的位置。 

      第三步:adb shell到设备,并起gdbserver侦听目标进程: 

adb shell 

gdbserver :5039 /system/bin/mediaserver 

      第四步: 建立pc机和设备的消息连接: 

    adb forward tcp:5039 tcp:5039 

      第五步: 使用gdb调试目标进程: 

cd android_src 

prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gdb out/debug/target/product/generic/symbols/system/bin/mediaserver 

      第六步: 设置符号表: 

set solib-absolute-prefix /your_android_src_path/out/debug/target/product/generic/symbols 

set solib-search-path /your_android_src_path/out/debug/target/product/generic/symbols/system/lib 

      第七步: 使gdb和gdb server建立连接: 

   target remote :5039 

      第八步: ok. 现在可以使用gdb的命令进行调试,譬如next\break\step\info thread等. 
(end)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值