Android 中 vector 反彙編示例
阿新 • • 發佈:2018-12-10
前言
最近遇到一個 native crash 問題,如下所示:(Android 8.1)
Revision: '0'
ABI: 'arm64'
pid: 1863, tid: 3348, name: Binder:1863_F >>> system_server <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8
Cause: null pointer dereference
x0 c200007682ae00c0 x1 0000000070556938 x2 0000000000000001 x3 000000761afa89d8
x4 00000000137 c0248 x5 0000000000000010 x6 0000000000000001 x7 0000000000000008
x8 0000000000000000 x9 238e9a517469cba9 x10 000000761afa89d4 x11 000000764e6e47b8
x12 0000000000000006 x13 0000000000000019 x14 0000000000000229 x15 0000000000000007
x16 000000761afa89d8 x17 0000000000000020 x18 0000000000000008 x19 0000000070556938
x20 0000000000000001 x21 000000761afa9588 x22 000000764eaa9300 x23 000000764eaa93f8
x24 000000764e623e73 x25 000000764e623e7b x26 0000000000000043 x27 000000761afa9588
x28 0000000000000059 x29 000000761afa88a0 x30 000000764e2dde4c
sp 000000761afa8860 pc 000000764e2cae80 pstate 0000000080000000
v0 0000000000000000ffffffffffffffff v1 000000761afa90a0000000761afa9110
v2 000000000000000075636553636e7953 v3 00000000000000000000000000000000
v4 00000000000000000000000000000000 v5 00000000000000004000000000000000
v6 00000000000000000000000000000000 v7 00000000000000008020080280200802
v8 00000000000000000000000000000000 v9 00000000000000000000000000000000
v10 00000000000000000000000000000000 v11 00000000000000000000000000000000
v12 00000000000000000000000000000000 v13 00000000000000000000000000000000
v14 00000000000000000000000000000000 v15 00000000000000000000000000000000
v16 40100401401004014010040140100401 v17 80080000000000008800000000404000
v18 80000800000000000000000000000000 v19 0000000000000000d362ff28f3dabbdf
v20 000000000000000000000000ebad8084 v21 000000000000000000000000ebad8085
v22 000000000000000000000000ebad8086 v23 000000000000000000000000ebad8087
v24 000000000000000000000000ebad8088 v25 000000000000000000000000ebad8089
v26 000000000000000000000000ebad808a v27 000000000000000000000000ebad808b
v28 000000000000000000000000ebad808c v29 000000000000000000000000ebad808d
v30 000000000000000000000000ebad808e v31 000000000000000000000000133c7810
fpsr 00000013 fpcr 00000000
backtrace:
#00 pc 0000000000215e80 /system/lib64/libart.so (art::gc::Heap::FindContinuousSpaceFromObject(art::ObjPtr<art::mirror::Object>, bool) const+68)
#01 pc 0000000000228e48 /system/lib64/libart.so (art::gc::Heap::IsMovableObject(art::ObjPtr<art::mirror::Object>) const+12)
#02 pc 0000000000382f04 /system/lib64/libart.so (art::JNI::GetStringCritical(_JNIEnv*, _jstring*, unsigned char*)+596)
#03 pc 000000000011342c /system/lib64/libandroid_runtime.so (android::android_os_Parcel_enforceInterface(_JNIEnv*, _jclass*, long, _jstring*)+76)
#04 pc 0000000000cc9254 /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.app.admin.SecurityLog.readEventsOnWrapping [DEDUPED]+180)
#05 pc 000000000177afc8 /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Parcel.enforceInterface+56)
#06 pc 00000000014f05ec /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.net.IConnectivityManager$Stub.onTransact+17724)
#07 pc 00000000009c017c /system/framework/arm64/boot-framework.oat (offset 0x9bd000) (android.os.Binder.execTransact+524)
#08 pc 0000000000549588 /system/lib64/libart.so (art_quick_invoke_stub+584)
#09 pc 00000000000dd178 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
#10 pc 000000000046d290 /system/lib64/libart.so (art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ArgArray*, art::JValue*, char const*)+100)
#11 pc 000000000046e718 /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+440)
#12 pc 0000000000347ed8 /system/lib64/libart.so (art::JNI::CallBooleanMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+624)
#13 pc 00000000000bba88 /system/lib64/libandroid_runtime.so (_JNIEnv::CallBooleanMethod(_jobject*, _jmethodID*, ...)+120)
#14 pc 000000000011f2cc /system/lib64/libandroid_runtime.so (JavaBBinder::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+156)
#15 pc 000000000004ae38 /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+136)
#16 pc 0000000000054e04 /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+532)
#17 pc 0000000000054b40 /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+156)
#18 pc 0000000000055178 /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+60)
#19 pc 00000000000761f8 /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24)
#20 pc 0000000000011460 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+280)
#21 pc 00000000000ab6a0 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140)
#22 pc 0000000000067e3c /system/lib64/libc.so (__pthread_start(void*)+36)
#23 pc 000000000001f280 /system/lib64/libc.so (__start_thread+68)
在反彙編 FindContinuousSpaceFromObject 方法的時候,始終理解的不太清楚,因此,使用 gdb 來輔助理解一下。因為 gdb 除錯過程當中,使用了一些 gdb 分析的常用技巧,並且新瞭解到了一些彙編知識,因此,將自己的一些收穫總結下來。(注:因為手頭的機器恰好是 Android 7.0 的,所以 gdb 除錯分析過程基於 Android 7.0,與上面的 log 略有不同)
一、FindContinuousSpaceFromObject
首先看一下 FindContinuousSpaceFromObject 方法的實現,基於 Android 7.0:
art/runtime/gc/heap.cc
space::ContinuousSpace* Heap::FindContinuousSpaceFromObject(const mirror::Object* obj,
bool fail_ok) const {
for (const auto& space : continuous_spaces_) {
if (space->Contains(obj)) {
return space;
}
}
if (!fail_ok) {
LOG(FATAL) << "object " << reinterpret_cast<const void*>(obj) << " not inside any spaces!";
}
return nullptr;
}
二、gdb 分析過程
首先,我們需要將斷點設定在 FindContinuousSpaceFromObject 方法處,通過:
nm libart.so | grep -i FindContinuousSpaceFromObject
我們可以知道 FindContinuousSpaceFromObject 對應的 symbol 為:
_ZNK3art2gc4Heap29FindContinuousSpaceFromObjectEPKNS_6mirror6ObjectEb
通過 b 來設定斷點,continue 使程式繼續執行:
通過 disass 檢視其對應的彙編程式碼:
Dump of assembler code for function art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const:
0x0000007fa15dd42c <+0>: stp x24, x23, [sp,#-64]!
0x0000007fa15dd430 <+4>: stp x22, x21, [sp,#16]
0x0000007fa15dd434 <+8>: stp x20, x19, [sp,#32]
0x0000007fa15dd438 <+12>: stp x29, x30, [sp,#48]
0x0000007fa15dd43c <+16>: add x29, sp, #0x30
0x0000007fa15dd440 <+20>: sub sp, sp, #0x10
0x0000007fa15dd444 <+24>: adrp x22, 0x7fa19f8000 <_ZTVN3art5arm6412Arm64ContextE+32>
0x0000007fa15dd448 <+28>: ldr x22, [x22,#1368]
0x0000007fa15dd44c <+32>: mov w20, w2
0x0000007fa15dd450 <+36>: mov x19, x1
0x0000007fa15dd454 <+40>: ldr x22, [x22]
0x0000007fa15dd458 <+44>: str x22, [sp,#8]
=> 0x0000007fa15dd45c <+48>: ldp x23, x21, [x0]
0x0000007fa15dd460 <+52>: cmp x23, x21
0x0000007fa15dd464 <+56>: b.eq 0x7fa15dd494 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+104>
0x0000007fa15dd468 <+60>: mov x24, x23
0x0000007fa15dd46c <+64>: ldr x0, [x24],#8
0x0000007fa15dd470 <+68>: mov x1, x19
0x0000007fa15dd474 <+72>: ldr x8, [x0]
0x0000007fa15dd478 <+76>: ldr x8, [x8,#8]
0x0000007fa15dd47c <+80>: blr x8
0x0000007fa15dd480 <+84>: and w8, w0, #0x1
0x0000007fa15dd484 <+88>: tbnz w8, #0, 0x7fa15dd530 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+260>
0x0000007fa15dd488 <+92>: cmp x21, x24
0x0000007fa15dd48c <+96>: mov x23, x24
0x0000007fa15dd490 <+100>: b.ne 0x7fa15dd468 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+60>
0x0000007fa15dd494 <+104>: and w8, w20, #0x1
0x0000007fa15dd498 <+108>: tbz w8, #0, 0x7fa15dd4a4 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+120>
0x0000007fa15dd49c <+112>: mov x0, xzr
0x0000007fa15dd4a0 <+116>: b 0x7fa15dd534 <art::gc::Heap::FindContinuousSpaceFromObject(art::mirror::Object const*, bool) const+264>
0x0000007fa15dd4a4 <+120>: adrp x1, 0x7fa195e000
0x0000007fa15dd4a8 <+124>: add x1, x1, #0xb83
0x0000007fa15dd4ac <+128>: mov x0, sp
0x0000007fa15dd4b0 <+132>: mov w2, #0x515 // #1301
0x0000007fa15dd4b4 <+136>: orr w3, wzr, #0x6
0x0000007fa15dd4b8 <+140>: mov w4, #0xffffffff // #-1
0x0000007fa15dd4bc <+144>: bl 0x7fa14be818 <art::LogMessage::LogMessage(char const*, unsigned int, art::LogSeverity, int)>
0x0000007fa15dd4c0 <+148>: mov x0, sp
0x0000007fa15dd4c4 <+152>: bl 0x7fa14be810 <art::LogMessage::stream()>
0x0000007fa15dd4c8 <+156>: adrp x21, 0x7fa195f000
0x0000007fa15dd4cc <+160>: add x21, x21, #0x806
0x0000007fa15dd4d0 <+164>: mov x20, x0
0x0000007fa15dd4d4 <+168>: orr w1, wzr, #0x8
0x0000007fa15dd4d8 <+172>: mov x0, x21
0x0000007fa15dd4dc <+176>: bl 0x7fa1497b00 <[email protected]>
0x0000007fa15dd4e0 <+180>: mov x2, x0
0x0000007fa15dd4e4 <+184>: mov x0, x20
0x0000007fa15dd4e8 <+188>: mov x1, x21
0x0000007fa15dd4ec <+192>: bl 0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long)>
0x0000007fa15dd4f0 <+196>: mov x1, x19
0x0000007fa15dd4f4 <+200>: bl 0x7fa14b5abc <std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(void const*)>
0x0000007fa15dd4f8 <+204>: adrp x20, 0x7fa195f000
0x0000007fa15dd4fc <+208>: add x20, x20, #0x80e
0x0000007fa15dd500 <+212>: mov x19, x0
0x0000007fa15dd504 <+216>: orr w1, wzr, #0x18
0x0000007fa15dd508 <+220>: mov x0, x20
0x0000007fa15dd50c <+224>: bl 0x7fa1497b00 <[email protected]>
0x0000007fa15dd510 <+228>: mov x2, x0
0x0000007fa15dd514 <+232>: mov x0, x19
0x0000007fa15dd518 <+236>: mov x1, x20
0x0000007fa15dd51c <+240>: bl 0x7fa14b5c74 <std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std