Android ClassLoader.loadClass 精灵坠毁

Android ClassLoader.loadClass JNI crash

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
  #00  pc 0x50f8e  /system/lib/libdvm.so (dvmAbort+89)
  #01  pc 0x59ee1  /system/lib/libdvm.so (dvmLinearAlloc(Object*, unsigned int)+64)
  #02  pc 0x76a7b  /system/lib/libdvm.so (???)
  #03  pc 0x76d77  /system/lib/libdvm.so (dvmDefineClass(DvmDex*, char const*, Object*)+10)
  #04  pc 0x71583  /system/lib/libdvm.so (???)
  #05  pc 0x30c0c  /system/lib/libdvm.so (???)
  #06  pc 0x343dc  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
  #07  pc 0x6d109  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+284)
  #08  pc 0x6d12d  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
  #09  pc 0x76e69  /system/lib/libdvm.so (dvmFindClassNoInit(char const*, Object*)+108)
  #10  pc 0x6216b  /system/lib/libdvm.so (???)
  #11  pc 0x62287  /system/lib/libdvm.so (???)
  #12  pc 0x65a6d  /system/lib/libdvm.so (dvmVerifyCodeFlow(VerifierData*)+9760)
  #13  pc 0x68c91  /system/lib/libdvm.so (???)
  #14  pc 0x68ce3  /system/lib/libdvm.so (dvmVerifyClass(ClassObject*)+42)
  #15  pc 0x7704d  /system/lib/libdvm.so (dvmInitClass+116)
  #16  pc 0x742d1  /system/lib/libdvm.so (???)
  #17  pc 0x30c0c  /system/lib/libdvm.so (???)
  #18  pc 0x343dc  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
  #19  pc 0x6ce39  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+344)
  #20  pc 0x73b19  /system/lib/libdvm.so (???)
  #21  pc 0x30c0c  /system/lib/libdvm.so (???)
  #22  pc 0x343dc  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
  #23  pc 0x6ce39  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+344)
  #24  pc 0x7431b  /system/lib/libdvm.so (???)
  #25  pc 0x30c0c  /system/lib/libdvm.so (???)
  #26  pc 0x343dc  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
  #27  pc 0x6d109  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+284)
  #28  pc 0x554af  /system/lib/libdvm.so (???)
  #29  pc 0x48c6b  /system/lib/libandroid_runtime.so (???)
  #30  pc 0x4a81f  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+394)
  #31  pc 0xf0d  /system/bin/app_process (???)
java.lang.Throwable: 
******* Java stack for JNI crash *******
    at dalvik.system.DexFile.defineClass(Native Method)
    at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:195)
    at dalvik.system.DexPathList.findClass(DexPathList.java:315)
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:58)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.lily.dexLoader.invokeStaticMethod(SourceFile:70)
    at com.lily.sdk.Web.<init>(SourceFile:77)

......

我无法通过我的 android 应用程序重现此崩溃,但监控系统多次报告此类崩溃。

不清楚是dex坏了还是系统dalvik不稳定

有没有人对这种 loadClass 崩溃有任何经验?

如果 VM 检测到严重问题,它将向日志发送诊断信息,然后中止。您正在使用的 Android 版本中的 VM 通过尝试写入只读位置 (0xdeadd00d) 而自行崩溃。

查看堆栈跟踪,dvmAbort() 之前的最后一件事是 dvmLinearAlloc()。查看 a recent source file,如果 VM 分配的内存不足,或者如果它无法在页面被积极标记为只读的特殊调试模式下更改页面上的权限,则 VM 将中止该函数。几乎可以肯定是前者。查看 logcat 输出可以肯定地告诉您。

假设您 运行 内存不足,我猜您是 运行 旧版本的 Android (<= gingerbread),其中 "linear alloc" 缓冲区过小。此内存区域用于保存 class 元数据,例如方法表和字段,而不是数据本身(这就是为什么可以将其标记为只读以帮助寻找内存垃圾)。避免该问题的唯一方法是重组 classes.

您可以在 this blog post.

中阅读有关此问题的更多信息以及 Facebook 工程师部署的解决方案