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.mkApplication.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/

编译完成后会在当前目录下生成一个libsobj目录如下:

$  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)可执行二进制文件相关推荐

  1. 使用 GDB 调试 Android 应用

    GNU 工程调试器(GDB)是一个常用的 Unix 调试器.本文详述使用 gdb 调试 Android 应用和进程的方法. 调试运行中的应用或进程 gdbclient 是源码库中的一个 shell 脚 ...

  2. Ubuntu下正确姿势使用GDB调试Android Native进程

        Ubuntu下正确姿势使用GDB调试Android Native进程 前言   对于Android Native进程大家是既爱又恨啊,爱的是它能为我们的Android世界带来别样的精彩,狠的是 ...

  3. Eclipse+CDT+GDB调试android NDK程序

    http://www.cnblogs.com/shadox/archive/2011/12/02/2272564.html Eclipse+CDT+GDB调试android NDK程序 Eclipse ...

  4. 使用GDB调试android模拟器

    使用android的模拟器可以调试应用,也可以调试C/C++代码库. 调试C/C++代码时,还可以使用GDB单步调试代码,跟linux上一样方便. 1. 准备android代码:从官网上下载代码,编译 ...

  5. gdb调试android

    手机端 adb shell gdbserver  --mulit *:23333 /data/local/tmp/test 电脑 target  remote 192.168.1.170:23333 ...

  6. android程序启动之后 eclipse ndk-gdb 连接,Eclipse+CDT+GDB调试android-NDK程序(补足六个汉字).docx...

    Eclipse+CDT+GDB调试android NDK程序 Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 1 ...

  7. GDB调试器——GDB调试器简介

    以下内容源于C语言中文网的学习与整理,如有侵权,请告知删除. 一.程序调试器的含义 程序中的错误主要分为 2 类,分别为语法错误和逻辑错误. 程序中出现的语法错误可以借助编译器解决:但逻辑错误则只能靠 ...

  8. 借助gdb调试glibc代码学习House of Orange

    转自: https://bbs.pediy.com/thread-251195.htm house_of_orange https://www.jianshu.com/p/1e45b785efc1 借 ...

  9. Android gdb调试

    Android对于C/C++代码的调试方式一般选用gdb+gdbserver的方式,其中gdbserver运行在目标系统中(如手机),gdb运行在宿主机上(如linux).gdb主要有以下几个功能: ...

最新文章

  1. mysql查询总结_mysql查询总结相关
  2. dom解析和sax解析的区别及优缺点
  3. 【拓扑排序】【DP】旅行计划(luogu 1137)
  4. java - 求素数
  5. 马云卸任浙江阿里小额贷款股份有限公司法定代表人、董事长
  6. Android Task 相关
  7. PKI与证书服务应用-要点总结
  8. 如何让原本的密码只执行一次_如何在虚拟机中正确的第一次启动Linux系统
  9. 【PostgreSQL-9.6.3】表空间
  10. 分布式系统的完整介绍
  11. 人机交互-语音交互的优势和劣势
  12. 后端学习路线的书籍经验总结
  13. 华为5G手机+鸿蒙系统,还能这么玩儿?
  14. python 图片识别_Python—识别图片中的文字
  15. 怎样查询SCI和EI检索号
  16. Could not find multidex.jar (com.android.support:multidex:1.0.2).
  17. 正则表达式re模式(python爬虫糗事百科热点段子)
  18. 数字藏品“秒杀风”背后的文博“新潮”
  19. 幻璃镜服务器维护中,仙剑奇侠传幻璃镜6.22更新_仙剑奇侠传幻璃镜6月22日更新维护公告_快吧手游...
  20. webdav映射网络驱动器有关问题

热门文章

  1. 建立高效的团队,可以做这七件事
  2. java关于hashmap编程题_在Java中,关于HashMap类的描述,以下说法错误的是( )。...
  3. Windows应用程序C#创建MDI父窗体和子窗体
  4. HTML中的表格及样式的设置
  5. uniapp 子组件 mounted 刷新
  6. Sparse Merkle Tree
  7. Linux (Ubuntu)c编程 (入门必看)
  8. 单片机计数器实验代码c语言,单片机计数器功能实验程序
  9. 如何在电脑上进行PDF压缩?
  10. [单片机框架] [kv_sys] 实现一个简易KV键值系统(最终版)