iOS汇编调试
最近项目出现线上奔溃,解crash的过程中调试了汇编,特此记录。
奔溃日志
OS Version: iPhone OS 9.2 (13C75)
Report Version: 104
Exception Type: SIGSEGV
Exception Codes: SEGV_MAPERR at 0x145e4bec8
Crashed Thread: 26
Thread 26 Crashed:
0 libobjc.A.dylib 0x00000001943c80b4 objc_retain + 20
1 libobjc.A.dylib 0x00000001943c812c objc_storeStrong + 44
2 AFWealth 0x0000000101af23dc -[SPDYSession initWithOrigin:configuration:cellular:error:] + 108
系统在objc_storeStrong的时候会retain对象,当线程25正在retain的时候,却发现该对象编程野指针了,导致retain奔溃,但从crash日志中没法看出是retain哪个对象的时候发生了变化。
找出这个对象就需要使用调试汇编。
储备知识
需要注意两点
- calling convention
- iOS的汇编代码是AT&T 语法的
汇编调试
根据crash堆栈打符号断点,命中后在objc_storeStrong打断点进行逐步调试。
id objc_storeStrong(id *object, id value) {
value = [value retain];
id oldValue = *object;
*object = value;
[oldValue release];
return value;
}
从上述源码可以知道,objc_storeStrong
有两个参数,第二个参数就是我们retain的对象。
0x1061ffb63 <+99>: movq %rcx, %rdi
0x1061ffb66 <+102>: movq %rdx, %rsi
0x1061ffb69 <+105>: callq 0x10764e60e ; symbol stub for: objc_storeStrong
根据FASTCALL的调用规范,我们查看rdx
寄存器的值。
(lldb) x/a $rdx
0x608001e60040: 0x00000001087bf8d0 (void *)0x00000001087bf8f8: SPDYConfiguration
或者
(lldb) po [$rdx class]
SPDYConfiguration
因而得之在这里被retain的是 SPDYConfiguration对象
结论
从上面的分析知道是有个SPDYConfiguration对象有多线程问题,然后再查查源码不久就解决问题了。