ARM 汇编回溯 PC 偏移量
ARM Assembly backtrace PC offset
ARM 手册提到:
During execution, PC does not contain the address of the currently
executing instruction. The address of the currently executing
instruction is typically PC-8 for ARM, or PC-4 for Thumb.
这是否也适用于崩溃回溯中的 PC
值?
例如,如果我有以下回溯(来自 Android armv7 设备,使用 ARM 指令):
libSomeLib.so!SomeClass::someMethod [someFile.cpp : 638 + 0x4]
r0 = 0x00000001 r1 = 0xffffffff r2 = 0x00000000 r3 = 0xd4fcd71c
r4 = 0xd39b9284 r5 = 0xd39b927c r6 = 0xd39b9278 r7 = 0xc7025520
r8 = 0xc5e1d7b0 r9 = 0xe01136a8 r10 = 0x00000012 r12 = 0xd39b9268
fp = 0xd39b92d4 sp = 0xd39b9268 lr = 0xd4ea1f24 pc = 0xd4ea1f24
...
0xd47cb000 - 0xd5079fff libSomeLib.so ???
我应该在 0xd4ea1f24-0xd47cb000=0x006D6F24
或 0xd4ea1f24-0xd47cb000-8=0x006D6F1C
处寻找 libSomeLib.so
中的崩溃指令吗?
我故意撞车是为了调查。源代码:
int* crashPointer = nullptr;
*crashPointer = 7;
生成的程序集:
11feb8: e3005007 movw r5, #7
11febc: e3006000 movw r6, #0 <--- r6 is #0
11fec0: e50b0014 str r0, [fp, #-20] ; 0xffffffec
11fec4: e50b1018 str r1, [fp, #-24] ; 0xffffffe8
11fec8: e51b0014 ldr r0, [fp, #-20] ; 0xffffffec
int* crashPointer = nullptr;
11fecc: e50b601c str r6, [fp, #-28] ; 0xffffffe4 <--- Stores #0 to [fp, #-28] from r6
*crashPointer = 7;
11fed0: e51b101c ldr r1, [fp, #-28] ; 0xffffffe4 <--- Loads #0 from [fp, #-28] to r1
11fed4: e5815000 str r5, [r1] <--- This should crash since it's trying to dereference r1 which is #0
预测的崩溃地址是11fed4
实际故障转储:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
r0 ea408800 r1 00000000 r2 00000006 r3 ea6ccfa0
r4 ea6d1b2a r5 00000007 r6 00000000 r7 ea3ff904
r8 00000001 r9 e8b22ec0 sl ea6b5be9 fp ea3ff5c0
ip ea6d1af8 sp ea3ff550 lr ea6d09aa pc ea696ed4 cpsr 600f0010
...
ea577000-ea6d7000 r-xp 00000000 fe:01 1556782 libSomeLib.so
结论:
ea696ed4-ea577000=11fed4
,等于预测地址
总而言之:无需向故障转储中的 PC 值添加偏移量(至少对于 Android armv7)。
ARM 手册提到:
During execution, PC does not contain the address of the currently executing instruction. The address of the currently executing instruction is typically PC-8 for ARM, or PC-4 for Thumb.
这是否也适用于崩溃回溯中的 PC
值?
例如,如果我有以下回溯(来自 Android armv7 设备,使用 ARM 指令):
libSomeLib.so!SomeClass::someMethod [someFile.cpp : 638 + 0x4]
r0 = 0x00000001 r1 = 0xffffffff r2 = 0x00000000 r3 = 0xd4fcd71c
r4 = 0xd39b9284 r5 = 0xd39b927c r6 = 0xd39b9278 r7 = 0xc7025520
r8 = 0xc5e1d7b0 r9 = 0xe01136a8 r10 = 0x00000012 r12 = 0xd39b9268
fp = 0xd39b92d4 sp = 0xd39b9268 lr = 0xd4ea1f24 pc = 0xd4ea1f24
...
0xd47cb000 - 0xd5079fff libSomeLib.so ???
我应该在 0xd4ea1f24-0xd47cb000=0x006D6F24
或 0xd4ea1f24-0xd47cb000-8=0x006D6F1C
处寻找 libSomeLib.so
中的崩溃指令吗?
我故意撞车是为了调查。源代码:
int* crashPointer = nullptr;
*crashPointer = 7;
生成的程序集:
11feb8: e3005007 movw r5, #7
11febc: e3006000 movw r6, #0 <--- r6 is #0
11fec0: e50b0014 str r0, [fp, #-20] ; 0xffffffec
11fec4: e50b1018 str r1, [fp, #-24] ; 0xffffffe8
11fec8: e51b0014 ldr r0, [fp, #-20] ; 0xffffffec
int* crashPointer = nullptr;
11fecc: e50b601c str r6, [fp, #-28] ; 0xffffffe4 <--- Stores #0 to [fp, #-28] from r6
*crashPointer = 7;
11fed0: e51b101c ldr r1, [fp, #-28] ; 0xffffffe4 <--- Loads #0 from [fp, #-28] to r1
11fed4: e5815000 str r5, [r1] <--- This should crash since it's trying to dereference r1 which is #0
预测的崩溃地址是11fed4
实际故障转储:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
r0 ea408800 r1 00000000 r2 00000006 r3 ea6ccfa0
r4 ea6d1b2a r5 00000007 r6 00000000 r7 ea3ff904
r8 00000001 r9 e8b22ec0 sl ea6b5be9 fp ea3ff5c0
ip ea6d1af8 sp ea3ff550 lr ea6d09aa pc ea696ed4 cpsr 600f0010
...
ea577000-ea6d7000 r-xp 00000000 fe:01 1556782 libSomeLib.so
结论:
ea696ed4-ea577000=11fed4
,等于预测地址
总而言之:无需向故障转储中的 PC 值添加偏移量(至少对于 Android armv7)。