Android 关于NDK Clang3.4 编译可执行文件无法启动的问题

来源:互联网 发布:程序员杂志订阅 编辑:程序博客网 时间:2024/06/07 02:06

1. 发现问题

今天遇到一个奇怪的问题:编写了一个C 的可执行二进制文件,利用ndk-build 编译后,调用如下代码执行该文件:

        public void run() {            Process process = null;            try {                process = Runtime.getRuntime().exec(“/data/data/package-name/files/myBinFile”);                if (process != null) {                    exit = process.waitFor();                }            } catch (Throwable t) {             }        }

发现在较老的机器上(Android OS <= ANDROID2.3)总是会失败:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***Build fingerprint: 'qcom/msm7627a/msm7627a:4.0.4/IMM76I/apkhot_xiumu_V0310:user/test-keys'pid: 11987, tid: 11987 >>> ./myBinFile <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00003e5cr0 70000001 r1 b00094fc r2 00000000 r3 00003e5cr4 b000a078 r5 ffffffff r6 00003e5c r7 be8a7b98r8 b0009910 r9 00000000 10 00000000 fp b0006e2bip 00003001 sp be8a7b58 lr 00002ce2 pc b00042c0 cpsr 00000030d0 0000000000000000 d1 0000000000000000d2 0000000000000000 d3 0000000000000000d4 0000000000000000 d5 0000000000000000d6 0000000000000000 d7 0000000000000000d8 0000000000000000 d9 0000000000000000d10 0000000000000000 d11 0000000000000000d12 0000000000000000 d13 0000000000000000d14 0000000000000000 d15 0000000000000000d16 0000000000000000 d17 0000000000000000d18 0000000000000000 d19 0000000000000000d20 0000000000000000 d21 0000000000000000d22 0000000000000000 d23 0000000000000000d24 0000000000000000 d25 0000000000000000d26 0000000000000000 d27 0000000000000000d28 0000000000000000 d29 0000000000000000d30 0000000000000000 d31 0000000000000000scr 00000000#00 pc b00042c0 /system/bin/linker#01 lr 00002ce2 <unknown>
而在高版本的机器上(Android OS > ANDROID2.3)却可以成功执行。百思不得其解,但怀疑肯定跟 android ndk 的编译环境有关。

于是将代码copy到同事的机器上用ndk 编译,奇迹发生了:同事的机器编译出来的BIN 文件却可以在ANDROID2.3 成功运行,为什么我的机器上编译出来的就不能运行呢?

后来发现我本地机器安装的NDK 版本是 ndk-r10d 而同事机器上安装的NDK 版本是 ndk-r9d。那么这两个版本的NDK编译出来的BIN文件到底有什么区别呢?

2. 分析问题

经过上面的对比分析,初步排除是BIN自身代码的问题,确定是跟编译器编译相关。接着用010 EDITOR打开ALIROOT_BIN文件,用ELF模板解析,发现其格式为:

天啊,三观崩溃,这是一个SO文件,但在高版本(Android OS > ANDROID2.3)的机器上可以直接执行。终于找到问题所在了,但仍有两个问题不解:

1. 明明指定编译输出为include $(BUILD_EXECUTABLE),怎么最终却编译生成Shared Library SO文件呢?ndk-r9d版toolchain 中的 Clang3.4 编译器没有这个问题,而ndk-r10d 版的toolchain 中的 Clang3.4 编译器存在这个问题。(Android NDK 这是要逆天了!)

2. 为什么SO格式的文件在Android 高版本(Android OS > ANDROID2.3)的机器上仍然可以直接执行?按理说是不能执行的才对啊,看来是我太孤陋寡闻了!

Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_LDLIBS := -llog -ldl LOCAL_CFLAGS += -DHAVE_PTHREADS -DANDROIDLOCAL_ARM_MODE := armLOCAL_SRC_FILES := myBinFile.cLOCAL_MODULE := myBinFileinclude $(BUILD_EXECUTABLE)
Application.mk

APP_PLATFORM := android-8NDK_TOOLCHAIN_VERSION=clang3.4

3. 解决问题

通过将Application.mk里的NDK_TOOLCHAIN_VERSION=clang3.4一行去掉,使得NDK采用默认GCC编译器编译,问题解决!

Application.mk

APP_PLATFORM := android-8
0 0
原创粉丝点击