art_quick_invoke_interface_tramp
2017-11-04 本文已影响696人
dumphex
问题现象
最近收到客户反馈的一个第三方App几乎必现bug.
- 复现步骤
- 手机(Android 6.0, 32bit CPU)
- 刷上gms版本
- 连上翻墙wifi, 打开play store, 提示升级
- 下载并安装第三方App: com.flipkart.android
- 打开App后,必现crash
定位分析
- 相关log
- tombstone
Revision: '0' ABI: 'arm' pid: 13920, tid: 13971, name: AsyncTask #5 >>> com.flipkart.android <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xf10174 r0 00f100f8 r1 a3ef3758 r2 00f100f8 r3 f4281c35 r4 b6ce7e40 r5 a3ef3794 r6 b6ce7e40 r7 a3ef37b0 r8 a3ef37a0 r9 71d96009 sl a3ef37ac fp a3ef37ac ip b4df5918 sp a3ef3720 lr b4d0283f pc b4c4ae76 cpsr 600b0030 d0 746e656d656c7063 d1 6920746f6e207365 d2 6c61757472695620 d3 45656e6968636127 d4 a3ef3ad8b4dc0528 d5 b4daa770b4daaa1c d6 b4daa940b4daaa44 d7 0000000100000000 d8 0000000000000000 d9 0000000000000000 d10 0000000000000000 d11 0000000000000000 d12 0000000000000000 d13 0000000000000000 d14 0000000000000000 d15 0000000000000000 d16 0000000000000000 d17 0000000000000000 d18 e4025aaef5998db7 d19 84009a117711baf7 d20 5a83f99993847c9a d21 5a8279995a827999 d22 8ecb34b68517d7d5 d23 267b77fb9a502286 d24 93ce4760edb98983 d25 5104571b527b7b18 d26 199bdf588148e7e5 d27 0e741e431450ae37 d28 5a8279995a827999 d29 5a8279995a827999 d30 0000000000000000 d31 0000000000000000 scr 20000010 backtrace: #00 pc 002a1e76 /system/lib/libart.so (_ZN3art6mirror5Class13GetDescriptorEPNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE+17) #01 pc 0035983b /system/lib/libart.so (_ZN3art16PrettyDescriptorEPNS_6mirror5ClassE+30) #02 pc 000a6ded /system/lib/libart.so (_ZN3art58ThrowIncompatibleClassChangeErrorClassForInterfaceDispatchEPNS_9ArtMethodEPNS_6mirror6ObjectES1_+236) #03 pc 003e747b /system/lib/libart.so (artInvokeInterfaceTrampoline+110) #04 pc 000e6579 /system/lib/libart.so (art_quick_invoke_interface_trampoline+40) #05 pc 71dc4af7 /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x1faf000)
- tombstone
初步分析
- gdb堆栈
(gdb) bt #0 std::__1::__c11_atomic_load<int> (__order=std::__1::memory_order_relaxed, __a=0xf10174) at external/libcxx/include/atomic:667 #1 std::__1::__atomic_base<int, false>::load (__m=std::__1::memory_order_relaxed, this=0xf10174) at external/libcxx/include/atomic:845 #2 art::Atomic<int>::LoadJavaData (this=0xf10174) at art/runtime/atomic.h:207 #3 art::mirror::Object::GetField<int, false> (field_offset=..., this=0xf100f8) at art/runtime/mirror/object-inl.h:738 #4 art::mirror::Object::GetField32<(art::VerifyObjectFlags)0, false> (field_offset=..., this=0xf100f8) at art/runtime/mirror/object-inl.h:598 #5 art::mirror::Class::GetPrimitiveType<(art::VerifyObjectFlags)0> (this=0xf100f8) at art/runtime/mirror/class-inl.h:556 #6 art::mirror::Class::IsPrimitive<(art::VerifyObjectFlags)0> (this=0xf100f8) at art/runtime/mirror/class.h:346 #7 art::mirror::Class::GetDescriptor (this=0xf100f8, storage=storage@entry=0xa3ef3758) at art/runtime/mirror/class.cc:715 #8 0xb4d0283e in art::PrettyDescriptor (klass=<optimized out>) at art/runtime/utils.cc:218 #9 0xb4a4fdf0 in art::ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch (interface_method=interface_method@entry=0x71d96009, this_object=<optimized out>, referrer=referrer@entry=0x6fd39b80) at art/runtime/common_throws.cc:221 #10 0xb4d9047e in art::artInvokeInterfaceTrampoline (interface_method=0x71d96009, this_object=0x12e01300, caller_method=0x6fd39b80, self=0xb9b169b8, sp=0xa3ef3980) at art/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc:2060 #11 0xb4a8f57c in art_quick_invoke_interface_trampoline () at art/runtime/arch/arm/quick_entrypoints_arm.S:350 #12 0x71dc4af8 in ?? ()
- 分析
-
#0反汇编分析
(gdb) disas Dump of assembler code for function art::mirror::Class::GetDescriptor(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*): 0xb4c4ae64 <+0>: stmdb sp!, {r4, r5, r6, r7, r8, lr} 0xb4c4ae68 <+4>: sub sp, #32 0xb4c4ae6a <+6>: ldr r4, [pc, #428] ; (0xb4c4b018 <art::mirror::Class::GetDescriptor(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)+436>) 0xb4c4ae6c <+8>: mov r2, r0 0xb4c4ae6e <+10>: add r4, pc 0xb4c4ae70 <+12>: ldr r4, [r4, #0] 0xb4c4ae72 <+14>: ldr r3, [r4, #0] 0xb4c4ae74 <+16>: str r3, [sp, #28] => 0xb4c4ae76 <+18>: ldr r5, [r0, #124] ; 0x7c ... ...
从这里分析来看,art::mirror::Class::GetDescriptor()的r0 = 0x00f100f8是导致问题出现的直接原因
-
r0的传递
r0最终是通过#11传入的, 而r0来自r9的第一个内存单元值
(gdb) x /4xw 0x71d96009 0x71d96009: Cannot access memory at address 0x71d96009
这里可以通过tombstone打印的寄存器值查看
71d96008 f100f8d0 0000be00 c004f8d0 f104f8dc ................ 71d96018 0000be00 00000000 f1d8f8d9 0000be00 ................ 71d96028 f23cf8d9 0000be00 f240f8d9 0000be00 ..<.......@..... 71d96038 f244f8d9 0000be00 001f8ec1 0002b789 ..D............. 71d96048 0054f764 00000000 00000000 00000000 d.T............. 71d96058 00000004 00004770 00000000 00000000 ....pG.......... 71d96068 00000000 00000080 00004de0 ffff0000 .........M...... 71d96078 00000076 4de0e92d 8a10ed2d 9000b089 v...-..M-....... 71d96088 1084f8cd 0c01f04f c008f8cd c0c4f8d9 ....O........... 71d96098 c004f8cd 0c04f20d c0c4f8c9 c084f8dd ................ 71d960a8 c00cf8cd d08cf8c9 f8d04648 47e0c1c0 ........HF.....G 71d960b8 a9039004 009cf8d9 c000f8dd c020f8dc .............. . 71d960c8 990447e0 f8d2464a 47e0c1d0 c084f8d9 .G..JF.....G.... 71d960d8 0f00f1bc b009d104 8a10ecbd 8de0e8bd ................
可以看到
-
出错的原因
- [0x71d96009] = 0x00f100f8
- [0x00f100f8 + 124] = [0xf10174],非法内存地址
-
r9 = 0x71d96009本身是非4字节对齐的
-
r9代表ArtMethod,其内容不是ArtMethod的正常值
-
r9位于boot.oat,这也是异常的
71d96000-73578000 r-xp 01faf000 b3:18 58373 /data/dalvik-cache/arm/system@framework@boot.oat
-
-
对比实验
刷上我司的基线版本,无论是否有gms, 都无法复现.
深入分析
前面分析了libart.so的相关堆栈,还需要深入分析boot.oat是怎么传输过来的ArtMethod异常值.
-
#12分析
-
pc offset
0x71dc4af7 - 0x6fde7000 - 0x1000 = 0x1fdcaf7
-
对应函数
public Throwable(String detailMessage) { this.detailMessage = detailMessage; this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT; fillInStackTrace(); }
-
native code
... ... 0x01fdcaea: 1c29 mov r1, r5 0x01fdcaec: 6808 ldr r0, [r1, #0] 0x01fdcaee: f8d001bc ldr.w r0, [r0, #444] 0x01fdcaf2: f8d0e024 ldr.w lr, [r0, #36] 0x01fdcaf6: 47f0 blx lr ... ...
-
分析
r1 = r5 = 0x12e01300 (gdb) x /4xw 0x12e01300 0x12e01300: 0x6f980410 0x00000000 0x12e01300 0x12c3d4f0 r0 = 0x6f980410 (gdb) x /4xw 0x6f980410+444 0x6f9805cc: 0x6fdaa678 0x6fdaa678 0x6fdaa678 0x6fdaa678 r0 = [0x6f980410 + 444] = 0x6fdaa678 (gdb) x /4xw 0x6fdaa678+36 0x6fdaa69c: 0x71d96029 0x00000000 0x00000000 0x00000000 lr = [0x6fdaa678 + 36] = 0x71d96029 offset = 0x71d96029 - 0x6fde7000 - 0x1000 = 0x1fae029 正好对应 art_quick_imt_conflict_trampoline Throwable构造函数调用fillInStackTrace(), 编译出的native code却跳转到art_quick_imt_conflict_trampoline(),这里说不通.
-
-
排查r5对象
- 查看r5对象
(gdb) p /x *('art::mirror::Throwable' *)0x12e01300 $74 = { <art::mirror::Object> = { static kVTableLength = 0xb, static hash_code_seed = { <std::__1::atomic<unsigned int>> = { <std::__1::__atomic_base<unsigned int, true>> = { <std::__1::__atomic_base<unsigned int, false>> = { __a_ = { __a_value = 0x473265d8 } }, <No data fields>}, <No data fields>}, <No data fields>}, klass_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f980410 }, <No data fields>}, monitor_ = 0x0 }, members of art::mirror::Throwable: cause_ = { <art::mirror::ObjectReference<false, art::mirror::Throwable>> = { reference_ = 0x12e01300 }, <No data fields>}, detail_message_ = { <art::mirror::ObjectReference<false, art::mirror::String>> = { reference_ = 0x12c3d4f0 }, <No data fields>}, stack_state_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x0 }, <No data fields>}, stack_trace_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f905e08 }, <No data fields>}, suppressed_exceptions_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f905c78 }, <No data fields>}, static java_lang_Throwable_ = { root_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f9680d0 }, <No data fields>} } }
- 查看对应的Class
(gdb) p /x *('art::mirror::Class' *)0x6f980410 $89 = { <art::mirror::Object> = { static kVTableLength = 0xb, static hash_code_seed = { <std::__1::atomic<unsigned int>> = { <std::__1::__atomic_base<unsigned int, true>> = { <std::__1::__atomic_base<unsigned int, false>> = { __a_ = { __a_value = 0x473265d8 } }, <No data fields>}, <No data fields>}, <No data fields>}, klass_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f95d1b8 }, <No data fields>}, monitor_ = 0x0 }, members of art::mirror::Class: static kClassWalkSuper = 0xc0000000, static kImtSize = 0x40, class_loader_ = { <art::mirror::ObjectReference<false, art::mirror::ClassLoader>> = { reference_ = 0x0 }, <No data fields>}, component_type_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x0 }, <No data fields>}, dex_cache_ = { <art::mirror::ObjectReference<false, art::mirror::DexCache>> = { reference_ = 0x6f8cafe0 }, <No data fields>}, dex_cache_strings_ = { <art::mirror::ObjectReference<false, art::mirror::ObjectArray<art::mirror::String> >> = { reference_ = 0x6f3ddae8 }, <No data fields>}, iftable_ = { <art::mirror::ObjectReference<false, art::mirror::IfTable>> = { reference_ = 0x6f8cbd48 }, <No data fields>}, name_ = { <art::mirror::ObjectReference<false, art::mirror::String>> = { reference_ = 0x6f62c478 }, <No data fields>}, super_class_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f97c2a8 }, <No data fields>}, verify_error_class_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x0 }, <No data fields>}, vtable_ = { <art::mirror::ObjectReference<false, art::mirror::PointerArray>> = { reference_ = 0x6f8ce7a0 }, <No data fields>}, access_flags_ = 0x80401, direct_methods_ = 0x6fbb0700, ifields_ = 0x0, sfields_ = 0x6fb1bf28, virtual_methods_ = 0x0, class_size_ = 0x90, clinit_thread_id_ = 0x299, dex_class_def_idx_ = 0x47c, dex_type_idx_ = 0x572, num_direct_methods_ = 0x2, num_instance_fields_ = 0x0, num_reference_instance_fields_ = 0x0, num_reference_static_fields_ = 0x0, num_static_fields_ = 0x1, num_virtual_methods_ = 0x0, object_size_ = 0x1c, primitive_type_ = 0x20000, reference_instance_offsets_ = 0x1f, status_ = 0xa, static java_lang_Class_ = { root_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f95d1b8 }, <No data fields>} } }
- 查看Class name
(gdb) p *('art::mirror::String' *)0x6f62c478 $90 = { <art::mirror::Object> = { static kVTableLength = 11, static hash_code_seed = { <std::__1::atomic<unsigned int>> = { <std::__1::__atomic_base<unsigned int, true>> = { <std::__1::__atomic_base<unsigned int, false>> = { __a_ = { __a_value = 1194485208 } }, <No data fields>}, <No data fields>}, <No data fields>}, klass_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 1872091144 }, <No data fields>}, monitor_ = 0 }, members of art::mirror::String: count_ = 29, hash_code_ = 3112926936, value_ = 0x6f62c488, static java_lang_String_ = { root_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 1872091144 }, <No data fields>} } } (gdb) x /1sh 0x6f62c488 0x6f62c488: u"java.lang.VirtualMachineError"
- 几个疑点
- 该对象实际为java.lang.VirtualMachineError类对象
- class_size_ = 0x90 = 144,怎么会访问offset = 444的内存?
- 查看r5对象
-
对比正常Throwable对象
- Throwable Class
(gdb) p /x *('art::mirror::Class' *)0x6f9680d0 $93 = { <art::mirror::Object> = { static kVTableLength = 0xb, static hash_code_seed = { <std::__1::atomic<unsigned int>> = { <std::__1::__atomic_base<unsigned int, true>> = { <std::__1::__atomic_base<unsigned int, false>> = { __a_ = { __a_value = 0x473265d8 } }, <No data fields>}, <No data fields>}, <No data fields>}, klass_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f95d1b8 }, <No data fields>}, monitor_ = 0x0 }, members of art::mirror::Class: static kClassWalkSuper = 0xc0000000, static kImtSize = 0x40, class_loader_ = { <art::mirror::ObjectReference<false, art::mirror::ClassLoader>> = { reference_ = 0x0 }, <No data fields>}, component_type_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x0 }, <No data fields>}, dex_cache_ = { <art::mirror::ObjectReference<false, art::mirror::DexCache>> = { reference_ = 0x6f8cafe0 }, <No data fields>}, dex_cache_strings_ = { <art::mirror::ObjectReference<false, art::mirror::ObjectArray<art::mirror::String> >> = { reference_ = 0x6f3ddae8 }, <No data fields>}, iftable_ = { <art::mirror::ObjectReference<false, art::mirror::IfTable>> = { reference_ = 0x6f8cbd48 }, <No data fields>}, name_ = { <art::mirror::ObjectReference<false, art::mirror::String>> = { reference_ = 0x6f6272b8 }, <No data fields>}, super_class_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f95db30 }, <No data fields>}, verify_error_class_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x0 }, <No data fields>}, vtable_ = { <art::mirror::ObjectReference<false, art::mirror::PointerArray>> = { reference_ = 0x0 }, <No data fields>}, access_flags_ = 0x80001, direct_methods_ = 0x6fd39b58, ifields_ = 0x6fb10ab8, sfields_ = 0x6fb10aa8, virtual_methods_ = 0x6fb96b98, class_size_ = 0x1f0, clinit_thread_id_ = 0x299, dex_class_def_idx_ = 0x87, dex_type_idx_ = 0x569, num_direct_methods_ = 0xc, num_instance_fields_ = 0x5, num_reference_instance_fields_ = 0x5, num_reference_static_fields_ = 0x0, num_static_fields_ = 0x1, num_virtual_methods_ = 0xd, object_size_ = 0x1c, primitive_type_ = 0x20000, reference_instance_offsets_ = 0x1f, status_ = 0xa, static java_lang_Class_ = { root_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f95d1b8 }, <No data fields>} } }
- 查看Class name
(gdb) p /x *('art::mirror::String' *)0x6f6272b8 $94 = { <art::mirror::Object> = { static kVTableLength = 0xb, static hash_code_seed = { <std::__1::atomic<unsigned int>> = { <std::__1::__atomic_base<unsigned int, true>> = { <std::__1::__atomic_base<unsigned int, false>> = { __a_ = { __a_value = 0x473265d8 } }, <No data fields>}, <No data fields>}, <No data fields>}, klass_ = { <art::mirror::ObjectReference<false, art::mirror::Class>> = { reference_ = 0x6f95d808 }, <No data fields>}, monitor_ = 0x0 }, members of art::mirror::String: count_ = 0x13, hash_code_ = 0x612cf26c, value_ = 0x6f6272c8, static java_lang_String_ = { root_ = { <art::mirror::ObjectReference<false, art::mirror::Object>> = { reference_ = 0x6f95d808 }, <No data fields>} } } (gdb) x /1sh 0x6f6272c8 0x6f6272c8: u"java.lang.Throwable"
- 查看method
- class_size_ = 0x1f0 = 496
- 虚函数表中的ArtMethod
(gdb) x /4xw 0x6f9680d0+444 0x6f96828c: 0x6fb96bc0 0x6fb96be8 0x6fb96c10 0x6fb96c38
- 相应的跳转函数
(gdb) x /4xw 0x6fb96bc0+36 0x6fb96be4: 0x71dc550d 0x6f9680d0 0x6f3be5e0 0x6f3bb090
- 查看offset对应method
(gdb) p /x 0x71dc550d - 0x6fde7000 - 0x1000 $12 = 0x1fdd50d 正好对应java.lang.Throwable.fillInStackTrace() 13: java.lang.Throwable java.lang.Throwable.fillInStackTrace() (dex_method_idx=13805) DEX CODE: 0x0000: 5410 e426 | iget-object v0, v1, [Ljava/lang/StackTraceElement; java.lang.Throwable.stackTrace // field@9956 0x0002: 3900 0300 | if-nez v0, +3 0x0004: 1101 | return-object v1 0x0005: 7100 f635 0000 | invoke-static {}, java.lang.Object java.lang.Throwable.nativeFillInStackTrace() // method@13814 0x0008: 0c00 | move-result-object v0 0x0009: 5b10 e326 | iput-object v0, v1, Ljava/lang/Object; java.lang.Throwable.stackState // field@9955 0x000b: 6200 7739 | sget-object v0, [Ljava/lang/StackTraceElement; libcore.util.EmptyArray.STACK_TRACE_ELEMENT // field@14711 0x000d: 5b10 e426 | iput-object v0, v1, [Ljava/lang/StackTraceElement; java.lang.Throwable.stackTrace // field@9956 0x000f: 1101 | return-object v1 OatMethodOffsets (offset=0x019cced0) code_offset: 0x01fdd50d
- Throwable Class
-
进一步结论
-
类的继承关系
public abstract class VirtualMachineError extends Error { } public class Error extends Throwable { } public class Throwable implements java.io.Serializable { }
-
VirtualMachineError是个抽象类,是不能实例化为对象的
-
目前唯一实例化的地方在art虚拟机
self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",...)
-
做实验证明,当在art虚拟机抛出VirtualMachineError异常时,确实会得到类似的堆栈.
- patch
diff --git a/runtime/thread.cc b/runtime/thread.cc index 5274f9e..146068f 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -1035,7 +1035,9 @@ struct StackDumpVisitor : public StackVisitor { last_method(nullptr), last_line_number(0), repetition_count(0), - frame_count(0) {} + frame_count(0) { + thread_in->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;", "tim test"); + } virtual ~StackDumpVisitor() { if (frame_count == 0) {
- 测试结果
Revision: '0' ABI: 'arm' pid: 1374, tid: 1378, name: Signal Catcher >>> com.android.settings <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x5540068 r0 05540054 r1 22cf02a0 r2 710da638 r3 ace70500 r4 b4cfc8e0 r5 fffff7ac r6 710da638 r7 05540054 r8 ace70500 r9 ace70500 sl 70f4d810 fp b6d38ec0 ip b4442eb0 sp b4442d90 lr b499651d pc b4c976f8 cpsr 000b0030 d0 b4d89500b6d4130c d1 b4d89508b6d34594 d2 b6d16627af803b48 d3 b4dac28070d1d580 d4 bb72184fb4cc7810 d5 b49d1c5bb4d9a248 d6 0000000000000001 d7 0000000000000001 d8 406a51eb851eb851 d9 3fedb6db6db6db6e d10 3fefd70a3d70a3d7 d11 3ff0000000000000 d12 406a51eb851eb851 d13 0000000000000000 d14 0000000000000000 d15 0000000000000000 d16 0000000000000003 d17 0000000000000000 d18 408f400000000000 d19 4078900000000000 d20 403c124924924925 d21 40db69db6db6db6e d22 408f400000000000 d23 406aa00000000000 d24 410a004000000000 d25 3fc47ae147ae1480 d26 406aa00000000000 d27 408f400000000000 d28 4064000000000005 d29 3fedb6db6db6db6e d30 3fefd70a3d70a3d7 d31 3ff0000000000000 scr 80000010 backtrace: #00 pc 003e76f8 /system/lib/libart.so (artInvokeInterfaceTrampoline+27) #01 pc 000e6519 /system/lib/libart.so (art_quick_invoke_interface_trampoline+40) #02 pc 73209af7 /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x2057000)
-
Google已于2016年底修复这一原生bug, patch在这里.
这说明当前堆栈并不是第一现场,需要合入该patch正常打印出异常后才知道哪里出了问题.
-
-
合入patch后,观察art正常抛出的异常
10-23 10:49:30.301 15871 15921 E AndroidRuntime: FATAL EXCEPTION: AsyncTask #3 10-23 10:49:30.301 15871 15921 E AndroidRuntime: Process: com.flipkart.android, PID: 15871 10-23 10:49:30.301 15871 15921 E AndroidRuntime: java.lang.RuntimeException: An error occurred while executing doInBackground() 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at android.os.AsyncTask$3.done(AsyncTask.java:310) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:242) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:235) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.lang.Thread.run(Thread.java:818) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: Caused by: java.lang.InternalError: Invoking Public Credential: with bad arg 0, type 'Ljava/lang/String;' not instance of 'Ljava/io/OutputStream;' 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.notification.c.sendFCMDataToBackend(MessagingUtils.java:87) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.notification.c.doRegisterForFCM(MessagingUtils.java:77) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.splash.InitHelper.b(InitHelper.java:75) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.splash.InitHelper.init(InitHelper.java:37) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.SplashActivity$a.doInBackground(SplashActivity.java:207) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at com.flipkart.android.SplashActivity$a.doInBackground(SplashActivity.java:191) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at android.os.AsyncTask$2.call(AsyncTask.java:296) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 10-23 10:49:30.301 15871 15921 E AndroidRuntime: ... 4 more
从异常堆栈中可看到,前面的VirtualMachineError已经变为InternalError了.
Root Cause
- App在运行过程中遇到异常,art虚拟机抛出VirtualMachineError. 而java.lang.VirtualMachineError是抽象类,不能实例化,且其类大小只有0x90=144个bytes, 当访问offset = 444内存时,必定越界,恰巧跳转到art_quick_invoke_interface_trampoline(),再往后,libart.so相关的堆栈基本就是错的了,相当于函数已经跑飞.
- 第三方App的异常还需要继续跟踪.
解决方案
- ART虚拟机抛出VirtualMachineError bug在Andriod 6.0/7.0./7.1中存在, Android 8.0已修复
- 第三方App抛异常的问题还须其它同事继续定位.