Android emulator中C代码的调试——gdb/gdbservers时遇到的坑
版权声明:本文为博主原创文章,未经博主允许不得转载。
先写个helloworld吧,在Android源码树中创建文件夹external/helloworld,加入文件:
// helloworld.c
#include <stdio.h>
#include <stdlib.h> int main(int argc, char** arv)
{
printf("Hello world~\n");
return ;
}
# Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := helloworld
LOCAL_CFLAGS += -march=armv4
LOCAL_SRC_FILES := $(call all-subdir-c-files)
include $(BUILD_EXECUTABLE)
执行
$ mmm external/helloworld
生成可执行文件。
- 启动模拟器并将待调试的文件上传到模拟器/data目录,(注意要传带调试信息的)
$ emulator&
$ adb push out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld /data
- 把gdbserver上传到模拟器
$ adb push prebuilts/misc/android-arm/gdbserver /data
我的平台是Mac OSX,在不同的平台下gdbserver的位置可能会不同。不过我发现在emulator的system/bin下面是有gdbserver的,所以如果不传,用这个默认的应该也可以。
- 在设备上通过gdbserver启动Native程序
$ adb shell gdbserver : /data/helloworld
- 在远程调试机器上把本地tcp端口forward到设备的tcp端口
$ adb forward tcp: tcp:
- 在远程调试机器上运行gdb
$ ./prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gdb out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld
gdb的路径会因平台而不同,helloworld要保证和模拟器上被调试的是同一个可执行程序。
- 接下来是gdb的具体调试命令
(gdb) target remote : # 连接到emulator的gdbserver
Remote debugging using :
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
Cannot access memory at address 0x0
0xb3446658 in ?? ()
(gdb) b main
Breakpoint at 0xb34665cc: file external/helloworld/helloworld.c, line .
(gdb) c
Continuing.
warning: Could not load shared library symbols for libraries, e.g. /system/bin/linker.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"? Breakpoint , main (argc=, arv=0xbe8c5ba4) at external/helloworld/helloworld.c:
printf("Hello world~\n");
(gdb) n
{
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
No /system/bin/linker
No /system/lib/libc++.so
No /system/lib/libc.so
No /system/lib/libm.so
No /system/lib/libnetd_client.so
(gdb) set solib-absolute-prefix out/target/product/generic/symbols/
Reading symbols from out/target/product/generic/symbols/system/bin/linker...done.
Loaded symbols for out/target/product/generic/symbols/system/bin/linker
Reading symbols from out/target/product/generic/symbols/system/lib/libc++.so...done.
Loaded symbols for out/target/product/generic/symbols/system/lib/libc++.so
Reading symbols from out/target/product/generic/symbols/system/lib/libc.so...done.
Loaded symbols for out/target/product/generic/symbols/system/lib/libc.so
Reading symbols from out/target/product/generic/symbols/system/lib/libm.so...done.
Loaded symbols for out/target/product/generic/symbols/system/lib/libm.so
Reading symbols from out/target/product/generic/symbols/system/lib/libnetd_client.so...done.
Loaded symbols for out/target/product/generic/symbols/system/lib/libnetd_client.so
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0xb3445e20 0xb345af18 Yes out/target/product/generic/symbols/system/bin/linker
0xb33bc920 0xb34032d8 Yes out/target/product/generic/symbols/system/lib/libc++.so
0xb331c8d0 0xb33685ac Yes out/target/product/generic/symbols/system/lib/libc.so
0xb32e8e30 0xb3300450 Yes out/target/product/generic/symbols/system/lib/libm.so
0xb32bcb08 0xb32be914 Yes out/target/product/generic/symbols/system/lib/libnetd_client.so
(gdb)……
这部分命令是纯调试功夫了,可是我遇到的大坑就在这!上面的顺序是连接到emulator、设置断点、continue断住、设置动态库搜索路径、开始调试……
说一下我遇到的坑及现象。我认为连接设备、设置搜索路径这些都属于环境的搭建和配置,所以都放到了前面执行。next了两步就收到了signal,说是非法指令:
(gdb) target remote :
Remote debugging using :
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
Cannot access memory at address 0x0
0xb1df5658 in ?? ()
(gdb) set solib-absolute-prefix out/target/product/generic/symbols/
Reading symbols from out/target/product/generic/symbols/system/bin/linker...done.
Loaded symbols for out/target/product/generic/symbols/system/bin/linker
(gdb) n
bl __linker_init
(gdb) n Program received signal SIGILL, Illegal instruction.
notify_gdb_of_load (info=0xbed759d8) at bionic/linker/linker.cpp:
rtld_db_dlactivity();
(gdb) l
rtld_db_dlactivity(); insert_soinfo_into_debug_map(info); _r_debug.r_state = r_debug::RT_CONSISTENT;
rtld_db_dlactivity();
} static void notify_gdb_of_unload(soinfo* info) {
if (info->is_main_executable()) {
(gdb)
此时还没有碰到helloworld就挂了,list查看当前的位置在bionic/linker/linker.cpp:194。
google了好多地儿,有的说这是Android4.1.2的一bug,这类文章大多是2012年的,而且号称是已经fix掉了(http://code.google.com/p/android/issues/detail?id=40941)。还有的地儿出主意说现在这一行上断住,然后修改PC寄存器(http://visualgdb.com/android/linker-sigill/)我看signal的位置是由arm指令跳转到thumb指令,我试过,修改之后又冒出别的问题。我是用的是Android官方6.0.1_r11正式版的代码数,不应该有这么严重的问题。
后来请教别的同事,发现他的操作就能完成完整的调试。跟我操作上最明显的差别就是他每次都会换一个映射端口,怀疑是用过的端口再次映射会出问题。然后我反复回溯他的调试过程,发现真正的原因在于gdb命令的执行过程——不要过早地设定so路径。
Android emulator中C代码的调试——gdb/gdbservers时遇到的坑的更多相关文章
- Android开发中使用代码删除数据库
更多信息参考:Android开发中使用代码删除数据库 在Android开发中,如果用到数据库,就会有一个很麻烦的问题,就是有时候需要删除数据库很麻烦,要打开Android Device Monitor ...
- Android开发中如何解决加载大图片时内存溢出的问题
Android开发中如何解决加载大图片时内存溢出的问题 在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...
- Android Studio在android Emulator中运行的项目黑屏
前言: 最近在做一个Android相关的小项目,因为之前这方面的项目做的比较的少.今天在使用虚拟机调试的时候经常出现一些莫名其妙的问题,经过自己多次的尝试和搜索终于解决了这些问题. 问题: 每次run ...
- android studio 中查找代码中的硬编码
在Android Studio中同时按下Ctrl + Shift+ F 或者其他自定义的快捷键,打开全局搜索,在全局搜索中输入 ^((?!(\*|//)).)+[\u4e00-\u9fa5] 并打勾 ...
- leetcode中,代码怎样调试,创造本地执行环境
初次接触leetcode,是我在一个招聘站点上看的,这个OJ真有那么厉害吗? 这几天在这个OJ上做了几道题,发现他的几个特点,1.题目不难(相对于ACM来说,我被ACM虐到至今无力),评判没那么苛刻, ...
- Android Studio 中设置代码块自动补齐
AS中很多提示键,并不如Eclipse中做的好,需要我们自己去自定义.这里以switch...case为例,讲解一下如何设置代码自动补全. 1.进入settings --> Editor -- ...
- Android webView 中loadData方法加载 带中文时出现乱码
WebView出现乱码用LoadData方法来解析html的,但是据说这是官方的一个BUG,不能用来解析中文. 采用loadDataWithBaseURL的方法,其中codeingType设置为utf ...
- Android NDK开发之C调用Java及原生代码断点调试(二)
上一篇中,我们主要学习了Java调用本地方法,并列举了两大特殊实例来例证我们的论据,还没学习的伙伴必须先去阅读下,本次的学习是直接在上一篇的基础上进行了.点击:Android NDK开发之从Java与 ...
- Android开发中代码下面出现波浪线问题
在Android Studio中写代码时,经常会在一个英文单词的下面出现波浪线,这是因为系统检测到你的这个英文单词不符合规范,如下所示: 解决办法:选中这个单词,点击鼠标右键,点击:Spelling ...
随机推荐
- Linux基础命令-文本文件查看工具
文本文件查看工具 cat concatenate 文本文件查看工具 cat /etc/fstab cat [OPTION]... [FILE]... -n:给显示的文本行编行 -E:显示行结束符 ta ...
- WPF案例:如何设计历史记录查看UI
(CSDN博客目前不支持外链, 只能纯文字) 设计WPF的UI,一般遵循下面的步骤: 1.首先分析数据结构 2.根据数据结构选择合理控件 3.定制外观 具体对于历史记录查看UI, 我们可以得知: 1. ...
- 蓝桥杯 基础练习 BASIC-15 字符串对比
基础练习 字符串对比 时间限制:1.0s 内存限制:512.0MB 问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字 ...
- JQ选择器大全
jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个 ...
- web聊天相关知识
http相关知识 http是无状态,请求,响应模式的通信模式,就是用户每次通过浏览器点击一下页面,都需要重新与web服务器建立一下连接,且发送自己的 session id 给服务器端以使服务器端验证此 ...
- Disconf —— 来自百度的分布式配置管理平台
摘要 为了更好的解决分布式环境下多台服务实例的配置统一管理问题,本文提出了一套完整的分布式配置管理解决方案(简称为disconf[4],下同).首先,实现了同构系统的配置发布统一化,提供了配置服务se ...
- 第八课 go的条件语句
1 if ... else package main import "fmt" func main() { flag:= { fmt.Println("flag > ...
- appium_python-测试报告模板话化
我们用python拓展模板 HTMLTestRunner.py python3 要自己重新改写下输出输入接口,可直接下载 改好的 地址 链接:http://pan.baidu.com/s/1hsOBw ...
- windows中git输错密码后不能重新输入的问题
当输入密码错误后,git会把密码保存在windows的你的当前用户名的缓存中. 我们可以在控制面板中寻找到这个缓存,再删掉就可以了. 首先,打开“控制面板”,把“查看方式”改为“大图标”,再打开“用户 ...
- 使用SQL Server保存Session状态,实现单点登录
在做一些应用网站时,我们可能会碰到这样一种情况:整个项目是由多个网站组成的,而我们要实现用户从一个站点登录后,跳转到其他网站不需要重复登录,即实现单点登录.目前实现单点登录的技术也有好几种,这篇文章描 ...