使用gdb调试Android(aarch 64)可执行二进制文件
Android官方提供了调试ndk进行
使用场景
在pc端编写Android可执行程序(注意不是App进程程序,这里指的是一个可执行文件比如linux的ELF文件、windows exe文件)
现在市面上基本是都是aarch64位的手机也就是arm64-v8a架构的cpu手机,当然,也可以通过adb shell 'cat /proc/cpuinfo'
进行查看
电脑手机模拟器的架构一般是x86架构,下面的教程要按你的架构去选择对应的文件
Main
Android是魔改的linux但是一些shell解释器是通用的,且核心架构还是linux内核,我们可以通过C语言编写Android下的可执行文件,首先如下文件:
demo.c
#include<stdio.h>
int main(){printf("hello \n");return 0;
}
在windows下可以通过软件一键运行、在Linux下可以gcc demo.c -o demo
、Mac clang demo.c -o demo
那么Android正常情况下是没有终端提供的,就需要电脑进行操作,clang+llvm可以实现进行多架构程序,当然这里不讲太深,在PC端下载Android-NDK
就可以得到一个NDK工具包一级目录如下:
21.0.6113669 » ls ~/Library/Android/sdk/ndk/21.0.6113669
CHANGELOG.md ndk-build prebuilt sysroot
NOTICE ndk-gdb python-packages toolchains
NOTICE.toolchain ndk-stack shader-tools wrap.sh
README.md ndk-which simpleperf
build package.xml source.properties
meta platforms sources
方便起见讲这个目录添加环境变量
export PATH=$PATH:~/Library/Android/sdk/ndk/21.0.6113669
然后在demo.c
的同级目录下编写配置文件(也可不同级,但是需要制定路径,这里为了方便),名字不能错Android.mk
、 Application.mk
具体的属性配置可以去官网配合着看
$ cat Android.mk ~/home/work# 一个Android.mk file首先必须定义好LOCAL_PATH变量。
# 它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’,
# 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
LOCAL_PATH := $(call my-dir)
# CLEAR_VARS由编译系统提供,
# 指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),除LOCAL_PATH 。这是必要的,
# 因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。
include $(CLEAR_VARS)
# LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须
是唯一的,而且不包含任何空格。
# 注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。
LOCAL_MODULE := demo
# LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,
# 因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文
件就好。
LOCAL_SRC_FILES := demo.c
# BUILD_EXECUTABLE 表示以一个可执行程序的方式进行编译
# BUILD_SHARED_LIBRARY 表示动态链接库的方式进行编译
include $(BUILD_EXECUTABLE)$ cat Application.mk ~/home/work
APP_ABI := armeabi-v7a arm64-v8a #这里是指定编译后的架构种类,如果全都要可以选择 all
APP_OPTIM := debug
然后就可以通过ndk-build
进行编译了它是基于cmake的有兴趣可以了解,非常强大的工具,在使用ndk-build
时需要对它指定编译环境参数,这里我封装成脚本:
$ cat load.sh
#!/bin/zshndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk NDK_DEBUG=1 NDK_HOST_32BIT=1 #32bit#adb push ./obj/local/arm64-v8a/$1 /data/local/tmp/
adb push ./obj/local/armeabi-v7a/$1 /data/local/tmp/
编译完成后会在当前目录下生成一个libs
和obj
目录如下:
$ ls ~/home/work
Android.mk demo.c libs obj
Application.mk gdb.sh load.sh
libs
libs
├── arm64-v8a
│ └── demo
└── armeabi-v7a└── demo
生成的就是指定的架构可执行文件, release version
obj
obj
└── local├── arm64-v8a│ ├── demo│ ├── objs│ │ └── demo│ │ ├── demo.o│ │ ├── demo.o.commands.json│ │ └── demo.o.d│ └── objs-debug│ └── demo│ ├── demo.o│ ├── demo.o.commands.json│ └── demo.o.d
对应的debug version具备符号表,可调试
具体从File Size可知:
$ du -sh libs/arm64-v8a/demo ~/home/work
8.0K libs/arm64-v8a/demo
$ du -sh obj/local/arm64-v8a/demo ~/home/work12K obj/local/arm64-v8a/demo
参数
#编译执行程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := demo.c
include $(BUILD_EXECUTABLE)
#会在obj/local/arm64-v8a/生成demo程序
#编译动态链接库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := demo.c
include $(BUILD_SHARED_LIBRARY)
#会在obj/local/arm64-v8a/生成libdemo.so库
调试
上面的脚本已经封装好了编译和推送到移动端在移动端则需要gdbserver
与PC端进行通信,ndk
工具集已经准备好了这个文件如下:
21.0.6113669 » adb push ./prebuilt/android-arm64/gdbserver/gdbserver /data/local/tmp
这里注意是push到手机的/data/local/tmp
路径下,这个是本地临时数据目录所以是低权限的、在这里就可以成功给上gdbserver
执行权限,然后通过开启服务端口的形式映射到网络层,命令如下:
adb shell "su -c '/data/local/tmp/gdbserver :9090 demo'"
#这里的:9090表示只要是同局域网都可以访问
#demo表示需要调试的可执行二进制文件
然后同局域网下的PC端就可以进行附加了,运行脚本如下:
$ cat gdb.sh ~/home/work
#!/bin/bash
adb forward tcp:9090 tcp:9090 #转发局域网端口到本地
gdb -ex "file ./obj/local/arm64-v8a/demo" \ #指定带有符号表的可执行文件-ex "set solib-search-path ./obj/local/arm64-v8a" \ #lib的路径,如果可执行文件依赖了lib就需要指定它-ex "target remote localhost:9090" #连接远程9090端口#-ex "set architecture aarch64" \#-ex "set solib-absolute-prefix ./" \#-ex "set architecture aarch64:ilp32" \
一键脚本
$ ls
gdb.sh load.sh start.sh
heif_decode_to_rgba.c png_to_yuv.c
目录下面应该有这些文件
gdb.sh
:运行附加gdb远程调试脚本load.sh
:编译项目脚本start.sh
:一键启动脚本xxx.c
:源文件
$ cat load.sh
#!/bin/bashndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk NDK_DEBUG=1 NDK_HOST_32BIT=1 #32bit#adb push ./obj/local/arm64-v8a/$1 /data/local/tmp/
adb push ./obj/local/armeabi-v7a/$1 /data/local/tmp/#----------------------------------------------------------------------------------------------
$ cat start.sh
#!/bin/bashfile="$1" #Input Compile FileNamerm -rf Android.mk Application.mk libs objif [ ! -d "./Android.mk" ];thenecho -e "LOCAL_PATH := \$(call my-dir)\ninclude \$(CLEAR_VARS)\nLOCAL_MODULE := $file\nLOCAL_SRC_FILES := $file.c\ninclude \$(BUILD_EXECUTABLE)" > Android.mk
fi
if [ ! -d "./Application.mk" ];thenecho -e "APP_ABI := armeabi-v7a arm64-v8a\nAPP_OPTIM := debug" > Application.mk
fi./load.sh $file#adb shell "su -c '/data/local/tmp/gdbserver :9090 /data/local/tmp/$file'"&#sleep 1
#./gdb.sh $file#----------------------------------------------------------------------------------------------
$ cat gdb.sh
#!/bin/bashadb forward tcp:9090 tcp:9090
gdb -ex "file ./obj/local/armeabi-v7a/$1" \-ex "set solib-search-path ./obj/local/armeabi-v7a" \ #我用的32bit!-ex "set architecture armv7e-m" \-ex "target remote localhost:9090" \-ex "b main" \-ex "c"#-ex "set architecture aarch64" \#-ex "set solib-absolute-prefix ./" \
大家按照注释取消开启对应需求
使用:
$ ./start.sh png_to_yuv #注意这里只需要写源代码的名字不用加.c
然后Android开启等待调试后,PC端进行附加
./gdb.sh
使用gdb调试Android(aarch 64)可执行二进制文件相关推荐
- 使用 GDB 调试 Android 应用
GNU 工程调试器(GDB)是一个常用的 Unix 调试器.本文详述使用 gdb 调试 Android 应用和进程的方法. 调试运行中的应用或进程 gdbclient 是源码库中的一个 shell 脚 ...
- Ubuntu下正确姿势使用GDB调试Android Native进程
Ubuntu下正确姿势使用GDB调试Android Native进程 前言 对于Android Native进程大家是既爱又恨啊,爱的是它能为我们的Android世界带来别样的精彩,狠的是 ...
- Eclipse+CDT+GDB调试android NDK程序
http://www.cnblogs.com/shadox/archive/2011/12/02/2272564.html Eclipse+CDT+GDB调试android NDK程序 Eclipse ...
- 使用GDB调试android模拟器
使用android的模拟器可以调试应用,也可以调试C/C++代码库. 调试C/C++代码时,还可以使用GDB单步调试代码,跟linux上一样方便. 1. 准备android代码:从官网上下载代码,编译 ...
- gdb调试android
手机端 adb shell gdbserver --mulit *:23333 /data/local/tmp/test 电脑 target remote 192.168.1.170:23333 ...
- android程序启动之后 eclipse ndk-gdb 连接,Eclipse+CDT+GDB调试android-NDK程序(补足六个汉字).docx...
Eclipse+CDT+GDB调试android NDK程序 Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 1 ...
- GDB调试器——GDB调试器简介
以下内容源于C语言中文网的学习与整理,如有侵权,请告知删除. 一.程序调试器的含义 程序中的错误主要分为 2 类,分别为语法错误和逻辑错误. 程序中出现的语法错误可以借助编译器解决:但逻辑错误则只能靠 ...
- 借助gdb调试glibc代码学习House of Orange
转自: https://bbs.pediy.com/thread-251195.htm house_of_orange https://www.jianshu.com/p/1e45b785efc1 借 ...
- Android gdb调试
Android对于C/C++代码的调试方式一般选用gdb+gdbserver的方式,其中gdbserver运行在目标系统中(如手机),gdb运行在宿主机上(如linux).gdb主要有以下几个功能: ...
最新文章
- mysql查询总结_mysql查询总结相关
- dom解析和sax解析的区别及优缺点
- 【拓扑排序】【DP】旅行计划(luogu 1137)
- java - 求素数
- 马云卸任浙江阿里小额贷款股份有限公司法定代表人、董事长
- Android Task 相关
- PKI与证书服务应用-要点总结
- 如何让原本的密码只执行一次_如何在虚拟机中正确的第一次启动Linux系统
- 【PostgreSQL-9.6.3】表空间
- 分布式系统的完整介绍
- 人机交互-语音交互的优势和劣势
- 后端学习路线的书籍经验总结
- 华为5G手机+鸿蒙系统,还能这么玩儿?
- python 图片识别_Python—识别图片中的文字
- 怎样查询SCI和EI检索号
- Could not find multidex.jar (com.android.support:multidex:1.0.2).
- 正则表达式re模式(python爬虫糗事百科热点段子)
- 数字藏品“秒杀风”背后的文博“新潮”
- 幻璃镜服务器维护中,仙剑奇侠传幻璃镜6.22更新_仙剑奇侠传幻璃镜6月22日更新维护公告_快吧手游...
- webdav映射网络驱动器有关问题
热门文章
- 建立高效的团队,可以做这七件事
- java关于hashmap编程题_在Java中,关于HashMap类的描述,以下说法错误的是( )。...
- Windows应用程序C#创建MDI父窗体和子窗体
- HTML中的表格及样式的设置
- uniapp 子组件 mounted 刷新
- Sparse Merkle Tree
- Linux (Ubuntu)c编程 (入门必看)
- 单片机计数器实验代码c语言,单片机计数器功能实验程序
- 如何在电脑上进行PDF压缩?
- [单片机框架] [kv_sys] 实现一个简易KV键值系统(最终版)