android - V8 独立应用程序仅在发布签名的 APK 时死于 SIGILL

标签 android c++ android-ndk v8

我正在使用嵌入到使用 Android NDK 的 C++ 应用程序中的 v8。它在许多设备上运行良好,但在使用发布签名 APK (Android 4.0.4) 的 Samsung Galaxy Tab 10.1 上崩溃。奇怪的是,调试签名的 apk 在 Galaxy Tab 10.1 上运行完美。我已经检查了调试/发布 apk 中的 .so 库,两者相等,md5 相同。

我创建了一个重现问题的最小测试用例。我测试了许多 v8 版本(3.22、3.23、3.26 等),有许多编译标志(armeabi、armeabi-v7a、-mfpu=vfpv3-d16 等),启用或禁用 v8 快照,但崩溃仍然存在在发布签名的 apk 中还活着。

如果两个 native .so 库相同,究竟是什么导致调试和发布签名的 apk 之间出现这种差异?有解决此崩溃的解决方法吗?

这是测试用例的main.cpp

#include "v8.h"
#include <jni.h>
#include <android/log.h>

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR  , "Paradox",__VA_ARGS__)

using namespace v8;

namespace {

    void testContext()
    {
        LOGE("Hellooo!!!");
        v8::Isolate* isolate = v8::Isolate::GetCurrent();
        v8::Locker v8Lock(isolate);
        v8::Isolate::Scope isolateScope(isolate);
        v8::HandleScope handle_scope(isolate);

        Handle<ObjectTemplate> global_templ = ObjectTemplate::New();

        LOGE("Creating V8 Context...");
        //crashes while creating this context
        v8::Handle<v8::Context> context = v8::Context::New(isolate, 0, global_templ);
        LOGE("Created V8 Context");
        v8::Context::Scope context_scope(context); 

        v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "'Hello' + ', World! ' + Math.PI");
        v8::Local<v8::Script> script = v8::Script::Compile(source);
        v8::Handle<v8::Value> result = script->Run();
        v8::String::Utf8Value utf8(result);
        LOGE("Yehaaaaa: %s", *utf8);
    }
}

extern "C"
{   
    jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        JNIEnv* env;
        if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
            return -1;
        }
        testContext();
        return JNI_VERSION_1_6;
    }  
}

应用.mk文件

APP_MODULES := Paradox
APP_ABI := armeabi-v7a
APP_PLATFORM := android-9
APP_STL := stlport_static

Android.mk文件

MY_LOCAL_PATH := $(call my-dir)

LOCAL_PATH := /Users/mortimer/Projects/v8/
include $(CLEAR_VARS)
LOCAL_MODULE := v8_android
LOCAL_SRC_FILES := \
    /Users/mortimer/Projects/v8/out/android_arm.release/obj.target/tools/gyp/libv8_base.arm.a
include $(PREBUILT_STATIC_LIBRARY)

LOCAL_PATH := /Users/mortimer/Projects/v8/
include $(CLEAR_VARS)
LOCAL_MODULE := v8_android_snapshot
LOCAL_SRC_FILES := \
    /Users/mortimer/Projects/v8/out/android_arm.release/obj.target/tools/gyp/libv8_snapshot.a
include $(PREBUILT_STATIC_LIBRARY)

LOCAL_PATH := $(MY_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := Paradox
LOCAL_C_INCLUDES := \
    /Users/mortimer/Projects/v8/include
LOCAL_STATIC_LIBRARIES := \
    v8_android \
    v8_android_snapshot

LOCAL_LDLIBS := \
    -llog \
    -lc
LOCAL_SRC_FILES := \
    main.cpp
include $(BUILD_SHARED_LIBRARY)

Android Activity

package com.mortimer.paradox;

import android.app.Activity;
import android.os.Bundle;

public class ParadoxActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        System.loadLibrary("Paradox");

        setContentView(R.layout.main);
    }
}

这是故障转储:

06-11 09:57:06.960    4198-4198/? D/dalvikvm﹕ Trying to load lib /data/data/com.mortimer.Paradox/lib/libParadox.so 0x4132f028
06-11 09:57:06.970    4198-4198/? D/dalvikvm﹕ Added shared lib /data/data/com.mortimer.Paradox/lib/libParadox.so 0x4132f028
06-11 09:57:06.970    4198-4198/? E/Paradox﹕ Hellooo!!!
06-11 09:57:06.990    4198-4198/? E/Paradox﹕ Creating V8 Context...
06-11 09:57:07.010    4198-4198/? A/libc﹕ Fatal signal 4 (SIGILL) at 0x5c60a310 (code=1)
06-11 09:57:07.150      110-180/? I/AudioPolicyManager﹕ stopOutput() output 1, stream 1, session 15
06-11 09:57:07.170      110-176/? I/AudioFlinger﹕ stop output streamType (0, 1) for 1
06-11 09:57:07.170      110-176/? D/AudioHardware﹕ AudioStreamOutALSA::setParameters() stop_output_streamtype=1
06-11 09:57:07.510      104-104/? I/DEBUG﹕ *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-11 09:57:07.510      104-104/? I/DEBUG﹕ Build fingerprint: 'samsung/GT-P7510/GT-P7510:4.0.4/IMM76D/XXLPH:user/release-keys'
06-11 09:57:07.510      104-104/? I/DEBUG﹕ pid: 4198, tid: 4198  >>> com.mortimer.Paradox <<<
06-11 09:57:07.510      104-104/? I/DEBUG﹕ signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 5c60a310
06-11 09:57:07.510      104-104/? I/DEBUG﹕ r0 00000002  r1 5c2080a1  r2 00000002  r3 3d93a1dd
06-11 09:57:07.510      104-104/? I/DEBUG﹕ r4 3d908091  r5 3d908091  r6 be859398  r7 3d908091
06-11 09:57:07.510      104-104/? I/DEBUG﹕ r8 3d933711  r9 0000000c  10 00a6888c  fp be859390
06-11 09:57:07.510      104-104/? I/DEBUG﹕ ip 00000056  sp be859384  lr 3ae51f18  pc 5c60a310  cpsr 20000010
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d0  431684be42700568  d1  3ff000004315d32c
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d2  457ff80000000fff  d3  000000003f000000
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d4  00001fff00000000  d5  3fe999999999999a
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d6  3fe8000000000000  d7  3f8000003f4ccccd
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d8  0000000000000000  d9  0000000000000000
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d10 0000000000000000  d11 0000000000000000
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d12 0000000000000000  d13 0000000000000000
06-11 09:57:07.510      104-104/? I/DEBUG﹕ d14 0000000000000000  d15 0000000000000000
06-11 09:57:07.510      104-104/? I/DEBUG﹕ scr 62000010
06-11 09:57:07.650      104-104/? I/DEBUG﹕ #00  pc 5c60a310
06-11 09:57:07.650      104-104/? I/DEBUG﹕ #01  lr 3ae51f18
06-11 09:57:07.650      104-104/? I/DEBUG﹕ code around pc:
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a2f0 ea000002 e3a0c03f e52dc004 eaffffff  ....?.....-.....
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a300 e307c1b8 e345cbfb e59cc000 e31c0040  ......E.....@...
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a310 1d6d0b20 024dd080 ed2d0b1c e92dffff   .m...M...-...-.
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a320 e59d2130 e1a0300e e28d4f4d e04b4004  0!...0..MO...@K.
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a330 e1a0500d e24dd00c e3cdd007 e58d5008  .P....M......P..
06-11 09:57:07.660      104-104/? I/DEBUG﹕ code around lr:
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 3ae51ef8 e30ac000 e345cc60 e92d4900 e3a0900c  ....`.E..I-.....
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 3ae51f08 e52d9004 e28db008 e1a0e00f e1a0f00c  ..-.............
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 3ae51f18 e30ac00c e345cc60 eafffff6 00000001  ....`.E.........
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 3ae51f28 00000002 000000b4 1fffffff 00000134  ............4...
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 3ae51f38 00000000 00000000 37d08289 0000032c  ...........7,...
06-11 09:57:07.660      104-104/? I/DEBUG﹕ memory map around addr 5c60a310:
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c609000-5c60a000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60a000-5c60b000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ 5c60b000-5c63c000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ stack:
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859344  00a6a268  [heap]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859348  00a68880  [heap]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85934c  00bd1738  [heap]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859350  00bd13ec  [heap]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859354  3d933711
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859358  3d908091
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85935c  00a6888c  [heap]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859360  be859390  [stack]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859364  5bd7c188  /data/data/com.mortimer.paradox/lib/libParadox.so
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859368  00000001
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85936c  5bd7c0f8  /data/data/com.mortimer.paradox/lib/libParadox.so
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859370  be859398  [stack]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859374  3d908091
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859378  df0027ad
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85937c  00000000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859380  3ae0be7c
06-11 09:57:07.660      104-104/? I/DEBUG﹕ #00 be859384  00000001
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859388  0000000c
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85938c  3d933711
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859390  be8593dc  [stack]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859394  3ae52748
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be859398  3d942861
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be85939c  be85947c  [stack]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593a0  3ae52381
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593a4  00000001
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593a8  3d933711
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593ac  be8593dc  [stack]
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593b0  3d908091
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593b4  3d908091
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593b8  3d908091
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593bc  00000000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593c0  00000000
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593c4  3d942861
06-11 09:57:07.660      104-104/? I/DEBUG﹕ be8593c8  3d9080c1

最佳答案

经过一些 v8 内部调试后,我已经解决了这个问题

问题是 V8 cpu 特征检测。 V8 通过/proc/cpuinfo 提取内核公开的信息。这是 Galaxy Tab 10.1 的 CPUInfo

E/Paradox ( 9512): Info-> Processor : ARMv7 Processor rev 0 (v7l)
E/Paradox ( 9512): processor    : 0
E/Paradox ( 9512): BogoMIPS : 1998.84
E/Paradox ( 9512): 
E/Paradox ( 9512): processor    : 1
E/Paradox ( 9512): BogoMIPS : 1998.84
E/Paradox ( 9512): 
E/Paradox ( 9512): Features : swp half thumb fastmult vfp edsp vfpv3 vfpv3d16 tls 
E/Paradox ( 9512): CPU implementer  : 0x41
E/Paradox ( 9512): CPU architecture: 7
E/Paradox ( 9512): CPU variant  : 0x1
E/Paradox ( 9512): CPU part : 0xc09
E/Paradox ( 9512): CPU revision : 0
E/Paradox ( 9512): 
E/Paradox ( 9512): Hardware : p3
E/Paradox ( 9512): Revision : 000e
E/Paradox ( 9512): Serial       : 4641120a0ab4919e
E/Paradox ( 9512): EO DATAAAAAAAAA

问题是特征字段同时具有 vfpv3 和 vfpv3d16 值(vfpv3d16 是一个有限的 vfpv3 版本,只有 16 个 64 位 FPU 寄存器)。

V8 解析 CPUInfo 时假设这两个值不是同时定义的:

if (HasListItem(features, "vfpv3")) {
  has_vfp3_ = true;
  has_vfp3_d32_ = true;
} else if (HasListItem(features, "vfpv3d16")) {
  has_vfp3_ = true;
}

修复:只需将 else 更改为新的 if,并将 has_vfp3_d32_ 设置为 false

if (HasListItem(features, "vfpv3")) {
  has_vfp3_ = true;
  has_vfp3_d32_ = true;
} 
if (HasListItem(features, "vfpv3d16")) {
  has_vfp3_ = true;
  has_vfp3_d32_ = false;
}

调试和发布签名的 apk 之间的区别在于,在调试版本中,V8 设法通过 ReadELFHWCaps 加载数据,但在发布签名的 apk 中,它回退到 CPUInfo。

关于android - V8 独立应用程序仅在发布签名的 APK 时死于 SIGILL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24160617/

相关文章:

c++ - 如何在 C++11 中输出枚举类的值

c++ - CMAKE - 将默认命令行参数添加到 cmake 项目

android - NDK 构建失败

java - 在Retrofit中使用Gson解析JSON

广播接收器的 Android java->kotlin 转换失败

android - 在 Android 中使用 play-services-auth 的 token 通过 Google Analytics Data API 进行身份验证

java - 如何在 JNI 中调用 String.getBytes()?我想在 JNI 中获取字节数组,但 CallByteMethod 只返回 jbyte 而不是 jbytearray

android - 在 android 中更新到 API 26 时 list 合并失败并出现多个错误

C++ 编译错误 : gnu_printf is an unrecognized format function type

linux - Make 继续使用原生 gcc 而不是 Android NDK