符号(方法和函数)的基址(程序计数器)不匹配。 关1

我的应用程序中有一些代码向我发送未捕获exception的堆栈跟踪。

"0 CoreFoundation 0x3ad073ff  + 186", "1 libobjc.A.dylib 0x39412963 objc_exception_throw + 30", "2 CoreFoundation 0x3ad0729d  + 0", "3 Foundation 0x39f3b7b3  + 90", "4 UIKit 0x34a3ae29  + 4184", "5 MyApp 0x0001feab -[MAMyClassA firstMethod:withParameter1:andParameter2:] + 374", "6 MyApp 0x000f76b5 -[MAMyClassB secondMethod:withParameter1:andParameter2:] + 164", "7 UIKit 0x34bd0fe1  + 84", "8 UIKit 0x34af2047  + 70", "9 UIKit 0x34af1ffb  + 30", "10 UIKit 0x34af1fd5  + 44", ... 

如您所见,Apple的大部分方法都被取代。 我已经能够使用nm从Apple的库中提取符号及其相应的基址,但地址不匹配。 他们离开1。

我已经计算了这里解释的地址: iOS崩溃报告:atos没有按预期工作 。

 Symbol address = (base address of framework) - (base address of symbol from crash report) + (virtual memory slide [vmaddr]). 

例如,我得到0xC2345,但nm返回的实际符号地址是0xC2344。 我知道这是正确的象征。 我在不同的框架(UIKit,Foundation,CoreFoundation等)中尝试了不同的崩溃报告中的不同地址,结果是一样的:值总是偏离1.我必须从我得到的中减去1崩溃报告以获取nm提供的“正确”地址。

当我输入这个问题时,我发现了这个: 来自otool for armv7的错误的方法实现地址? 。

这是否意味着每次我有一个地址要查找我必须执行以下逻辑?

 if ((symbol address) mod 2 == 1) { // This is a thumb instruction so it may be 2 or four bytes Subtract 1 from the symbol address and then use it to lookup the symbol. } else { // This is a standard 4-byte ARM instruction. Perform symbol lookup with the address as is. } 

提前感谢您的任何帮助或指导。

PC中的LSB显示当前的执行模式。 如果该位为0则为ARM,如果将其设置为1,则执行在Thumb-Mode中完成。 所以,是的,你会得到这样的真实地址:

 real_address = address & ~1; 

而目前的执行模式如下:

 is_thumb_mode = address & 1; 

目前大多数代码都将编译为Thumb-2,因为它只有少数区域缺少“真正的”ARM代码,通常可以节省大约30%的代码大小。