admin 管理员组文章数量: 887007
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/zsh
ndk-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.omands.json
│ │ └── demo.o.d
│ └── objs-debug
│ └── demo
│ ├── demo.o
│ ├── demo.omands.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/work
12K 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库
调试
补补补,之前都是用Mac OS在调试的,没发现什么问题。今天用Ubuntu来调试一直报错:Starting program: /home/hi/tmp/obj/local/arm64-v8a/demo
Failed to execute process ‘/home/hi/tmp/obj/local/arm64-v8a/demo’. Reason:
exec: unknown error (errno was 8)
The file ‘/home/hi/tmp/obj/local/arm64-v8a/demo’ is marked as an executable but could not be run by the operating system.
During startup program exited with code 126.
给我恶习到了,最后发现我少安装了一个gdb-multiarch,将gdb使用gdb-multiarch来代替就可以调试上去了。。。。。
上面的脚本已经封装好了编译和推送到移动端在移动端则需要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 'cd /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/bash
ndk-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/bash
file="$1" #Input Compile FileName
rm -rf Android.mk Application.mk libs obj
if [ ! -d "./Android.mk" ];then
echo -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" ];then
echo -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/bash
adb 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
本文标签: 可执行 二进制文件 Android gdb aarch
版权声明:本文标题:使用gdb调试Android(aarch 64)可执行二进制文件 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1733947180h1646070.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论