我已经从 iOS 应用程序的 dSYM 文件中解析出地址、文件名和行号。我基本上有一个将地址映射到文件名和行号的表,这对调试很有帮助。
为了获得actual lookup address
,我使用崩溃报告中的堆栈跟踪地址并使用此答案中指定的公式:https ://stackoverflow.com/a/13576028/2758234 。所以像这样。
(actual lookup address)
= (stack trace address) + (virtual memory slide) - (image load address)
我使用那个地址并在我的桌子上查找它。我得到的文件名是正确的,但是行号始终指向被调用的函数或方法的末尾,而不是在堆栈跟踪上调用以下函数的实际行。
我在某处读过,不记得在哪里,必须取消标记帧地址,因为它们对齐以使系统指针大小加倍。所以对于 32 位系统,指针大小是 4 字节,所以我们使用 8 字节去标记,使用如下公式:
(de-tagged address) = (tagged address) & ~(sizeof(uintptr_t)*2 - 1)
其中uintptr_t
是用于 Objective-C 中指针的数据类型。
这样做之后,查找排序工作,但我必须做一些事情,比如找到小于或等于去标签地址的最近地址。
问题 #1:
为什么我必须取消标记堆栈帧地址?为什么堆栈跟踪中的地址没有指向正确的位置?
问题 #2:
有时在崩溃报告中似乎缺少帧。例如,如果function1()
调用function2()
which callsfunction3()
which callsfunction4()
,在我的堆栈跟踪中,我将看到如下内容:
0 Exception
1 function4()
2 function3()
4 function1()
并且(上面的第 2 帧)的堆栈跟踪地址function3()
甚至没有指向正确的行号(但它是正确的文件),即使在取消标记之后也是如此。即使我让 Xcode 表示崩溃报告,我也看到了这一点。
为什么会这样?