目标:
我想象征着"输出" [NSThread callStackSymbols]
.
附注:
我知道如何使用崩溃日志来做到这一点.但是,我需要调查一些我想查看调用堆栈的问题.不幸的是,这些天框架的地址都是
.导致在正确的点崩溃(或结尾-看到我的问题的结束)是不是真的可以接受的,但如果我不能找到另一种解决方案,这将是要走的路.
我必须在设备上运行我的测试,所以我不能使用模拟器.
目前的做法:
当我这样称呼:
NSLog(@"call stack:\n%@", [NSThread callStackSymbols]);
我得到这个输出:
2015-12-08 15:04:03.888 Conversion[76776:4410388] call stack: ( 0 Conversion 0x000694b5 -[ViewController viewDidLoad] + 128 1 UIKit 0x27259f55+ 1028 ... 9 UIKit 0x274f67a7 + 134 10 FrontBoardServices 0x2b358ca5 + 232 11 FrontBoardServices 0x2b358f91 + 44 12 CoreFoundation 0x230e87c7 + 14 ... 16 CoreFoundation 0x23038ecd CFRunLoopRunInMode + 108 17 UIKit 0x272c7607 + 526 18 UIKit 0x272c22dd UIApplicationMain + 144 19 Conversion 0x000767b5 main + 108 20 libdyld.dylib 0x34f34873 + 2 )
(此输出中的"转换"是应用程序.)
现在我可以使用此命令"符号化"地址:
xcrun atos -o /path/to/Conversion.app -arch arm64 -l 0x0???
像那样运行(当然有适当的值-l
),我可以输入类似的地址0x000694b5
,它会吐出类似的东西-[ViewController viewDidLoad] + 128
.当然问题是起始地址(-l选项的值).
当我有崩溃日志时,我可以得到那些.但是,我想在没有崩溃的情况下逃脱.
问题:
Q1:我可以在运行时确定起始地址,也可以将其包含在日志输出中,以便将其提供给atos -l
选项吗?
编辑:它看起来像这可能是这样的:(感谢NSProgrammer的答案/sf/ask/17360801/)
#import... intptr_t slide = _dyld_get_image_vmaddr_slide(0); const struct mach_header * load_addr = _dyld_get_image_header(0); NSLog(@"slide %lx load addr %lx", (long)slide, (long)load_addr);
/编辑
(因为我对框架的方法调用感兴趣,我当然需要框架的起始地址.应用程序的起始地址经常更改(随机化),我还不知道,框架的起始地址是否随机化.)
Q2:是否有其他方法来调查调用堆栈中的方法?(断点在我的场景中也相当笨拙.)
编辑:
问题3:我如何表示框架的地址?例如,我在哪里可以找到UIKit的dSYM(或任何需要的东西)?
(例如我有一些东西:~/Library/Developer/Xcode/iOS\ DeviceSupport/9.1\ \(13B143\)/Symbols/System/Library/Frameworks/UIKit.framework/
.我会在这里查看更多细节.)
/编辑
也许解决方案:
一种方法是,将日志输出保存到文件,并在测试结束时导致应用程序崩溃.这样崩溃日志会显示起始地址,并且通过日志中的调用堆栈信息,我应该能够对callStackSymbols
输出进行符号化.我会尝试下一步.