android 调试 native 程序的方法
一、背景
首先说需求,这个需求非常常见,就是android上需要的一个功能,linux已经有开源代码而且非常稳定,希望能直接porting过去使用,这个程序是pure c 的代码,也就是说,跟android framework, java 没关系,也跟jni没有关系,我们希望的就是能编译成一个可执行工具,push到android后能直接跑起来使用。
既然是native 代码,主要影响到的就是bionic libc, 因为android的这个基础库跟 linux 上常见的 gnu libc 有区别,主要是被精简了,至于更具体理解什么叫被精简,建议找个linux 开源工具代码在 android ndk 环境里编一下就知道了,其实,这里边还隐藏另外两层区别,一个是 android api level, 就是所谓的android 版本,比如 android 4.4.4 对应 android API 19, android 5 对应 android API 21 , 不同版本的 bionic libc 本身也是有区别的。 另一个是 abi , 就是体系架构的区别,比如 x86, x86_64, armeabi -v7a 等等,不同 abi 设置下 bionic libc 用到的接口也不一样。上面这两个影响会导致,你的代码可能在 API 21 编译通过了,但是在 API 19 失败,或者,在 armeabi-v7a 成功了,但是在 arm64-v8a 失败了。这两点的处理放在另外的文章说明,这篇文章不考虑。可以认为,我们暂时不考虑编译出来的工具的通用性,只在特定的目标,如 abi = armeabi-v7a, api = 21 的android devices 上运行。
好了,我们已经编成功了这个工具,push 到目标设备后(或模拟器)发现运行出现段错误,这是非常常见的,因为在移植过程中,我们把某些 glibc 的调用替换成了 bionic 的调用,接下去应该怎么调试呢?首先说这里的调试,当然是源码级别的单步调试,就是我们在 linux 上开发并调试程序一样。这个要求看似简单,但我搜索了一天的时间,尝试了多种方式,最后才找到一种简单可用且匹配需求的方式。
二、方法
首先,尝试搜索 gdb-for-arm 的工具,就是看有没有一个 gdb 可执行程序,是可以直接在 android arm devices 上运行的,如果有的话,就跟直接在 linux 环境里调试一样了,可惜,这么简单的需求,都搜索不到
下面都是尝试用远程调试的方式
第一种,客户端在win7. 使用 ida pro 6.6 , 它提供了一个 android_server 可以用来push到 android 系统里运行,然后在 ida 的界面里 run remote 可执行程序,这种方式可以跑起来,可以单步执行、可以下断点,但是无法加载正确的符号表。
第二种,客户端在win7,找了一个 http://gnutoolchains.com/android/ 为android 编译好的 gnu tool chains 网站,下载 gdbserver 和 gdb.exe , gdbserver push到目标机器跑起来,本地用 gdb.exe 启动,使用gdb 远程调试那套步骤进行设置,发现也是能够跑起来,还是无法正确加载符号表。
第三种,客户在在win7,使用 Cygwin 的方式跑gdb客户端,启动之后 cygwin 报了一个长度太长的问题,没有深入去解决
从这里开始,突然对在win7 下启动 gdb 客户端有些失望,随即改为在 ubuntu14.04 里启动 gdb 客户端, android 模拟器也在 ubuntu 里启动。这里的 ubuntu 跑在 win7 上的 vmware 里。具体如果在 ubutnu 里下载并配置 android sdk 开发环境,并创建 avd , 启动 avd, 可以从网上搜索,最终就是在 ubuntu 里正常启动一个 android emulator.
然后,就使用下面的方式,就是可以源代码单步调试了:
4. 在设备上通过gdbserver运行你的程序
android 调试 native 程序的方法的更多相关文章
- ubuntu下整合eclipse和javah生成jni头文件开发android的native程序
0:前言: 这两天一直在研究用android的jni调用第三方库,上网搜方法,但是都是泛泛而谈,没有demo,经过我几番折磨,写了n多的helloword工程,总是不成功,工程名字也就由helloow ...
- 调试 Android* x86 应用程序的方法以及要使用的工具
作者:Xiaodong Wang 1.简单介绍 众所周知,Android* 开发者头顶很多称呼:设计员.程序员等,而且一般会不可避免地被称为故障检修工. 代码中的错误无法避免.因此不管您是否一開始就造 ...
- [Android设计模式]Android退出应用程序终极方法
如何干净彻底地退出Android应用程序,是很多开发者的心头痒.如何干净地关闭所有已打开的Activity? 如何关闭指定的Activity? 如何关闭一类Activity? 这里,我们提出一种通过实 ...
- php异步调试和线上调试网站程序的方法
当碰到一个网站需要不间断运行,但又需要调试该网站的程序错误的时候,该如何办呢?是靠经验一点点猜测,还是直接打印错误信息让其在页面输出? 下面分享一种方法同时满足这两种条件,既方便网站程序错误调试,又不 ...
- ubuntu下整合eclipse和javah生成jni头文件开发android的native程序(转)
本文介绍两种利用javah命令生成jni头文件的方法,第一种为大众所知的javah命令,第二种为整合javah到eclipse里面.推荐第二种方式,方便快捷,随时修改随时生成 0:前提和条件: 1:u ...
- Android下用程序的方法为ListView设置分割线Divider样式
使用XML的时候可以使用android:divider属性为ListView设置分割线的样式(颜色或者资源文件),而在Java代码中默认提供的方法 listView.setDivider() 却只支持 ...
- [转]ubuntu下整合eclipse和javah生成jni头文件开发android的native程序
转载自:http://blog.csdn.net/jiuyueguang/article/details/9404237 本文介绍两种利用javah命令生成jni头文件的方法,第一种为大众所知的jav ...
- 调试CEF3程序的方法
CEF3多进程模式调试时按F5只会启动调试Browser进程,要调试Renderer进程就要让进程在启动时就暂停并附加进程. 所幸google早就想到了这一点,chrome的命令行参数就可以办到, - ...
- Android 调试native的crash和anr
1. 于trace找到相应的库.例如 liba.so和相应的地址信息 2. 采用addr2line 查看 addr2line 住址 -e liba.so -f 要么 arm-eabi-addr2lin ...
随机推荐
- Google无法离线安装扩展程序
Google无法离线安装扩展程序 Chrome插件伴侣 按照里面的使用说明使用 网盘地址: 链接: https://pan.baidu.com/s/1eXoLXyPNl2pfoPnArHq2Lg 提取 ...
- 2.爬虫 urlib库讲解 异常处理、URL解析、分析Robots协议
1.异常处理 URLError类来自urllib库的error模块,它继承自OSError类,是error异常模块的基类,由request模块产生的异常都可以通过这个类来处理. from urllib ...
- Python——数据类型之dict
字典,相当于一个列表,不过列表的索引是数字,字典的索引是数字或者字符串. 1.字典的访问 字典是典型的key-value结构,一个key对应着一个value,key就是索引,value就是要保存的值 ...
- jira+mysql+破解+中文+compose
1.制作docker-compose.yml 2.安装 $ docker stack deploy -c docker-compose.yml mshk_jira
- 第一课:SVN代码管理
SVN:是一个跨平台的开源的版本控制系统.svn版本管理工具管理着随时间改变的各种数据.这些数据放置在一个中央资料档案库中.svn会备份并记录每个文件每次的修改更新变动.svn的工作流程:1.在中央库 ...
- int,long,long long类型的范围
[内置类型] int -2147483648-2147483647 //现在编译器的int型是32位的,以前为16位的范围是-32768~32767 unsigned int 0-4 ...
- Android Service 服务(三)—— bindService与remoteService
(转自:http://blog.csdn.net/ithomer/article/details/7366396) 一.bindService简介 bindService是绑定Service服务, ...
- HTML文档插入JS代码的几种方法
在HTML文档里嵌入客户端JavaScript代码有4中方法: 1.内联,放置在< script>和标签对之间. 2.放置在由< script>标签的src属性指定的外部文件中 ...
- fork开源代码后如何基于某个tag建立自己的branch
应用场景: 在github上fork一个自己想看的开源项目,想基于某个tag来写一些测试demo,然后可以做到版本控制. 方法: //克隆 git clone xxxxx.git //查看tag gi ...
- vue2.0中父子组件之间的通信总结
父组件: 子组件: 接受父组件的信息: 向父组件发送事件: (其中slot是插槽,可以将父组件中的<p>123</p>插入进来,如果父组件没有插入的内容,则显示slot内部的内 ...