这是来自a user's crash report的调用堆栈:
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 com.growl.GrowlSafari 0x179d383c writeWithFormat + 25
1 com.growl.GrowlSafari 0x179d388e writeWithFormat + 107
2 com.growl.GrowlSafari 0x179d388e writeWithFormat + 107
3 com.growl.GrowlSafari 0x179d388e writeWithFormat + 107
4 com.growl.GrowlSafari 0x179d388e writeWithFormat + 107
5 com.growl.GrowlSafari 0x179d388e writeWithFormat + 107
迹线在第511帧处截止。
这是writeWithFormat
:
int writeWithFormat(FILE *file, NSString *format, ...) {
va_list args;
va_start(args, format);
int written = writeWithFormatAndArgs(file, format, args);
va_end(args);
return written;
}
正如你所看到的,它并没有自称。
这是它所调用的功能:
int writeWithFormatAndArgs(FILE *file, NSString *format, va_list args) {
return 0;
return fprintf(file, "%s\n", [[[[NSString alloc] initWithFormat:format arguments:args] autorelease] UTF8String]);
}
(正如你猜测的那样,这是记录未被激活的代码。)
那么,这段代码如何导致堆栈跟踪?
使用otx进行反汇编:
_writeWithFormatAndArgs:
+0 00000f68 55 pushl %ebp
+1 00000f69 89e5 movl %esp,%ebp
+3 00000f6b 31c0 xorl %eax,%eax
+5 00000f6d c9 leave
+6 00000f6e c3 ret
_writeWithFormat:
+0 00001823 55 pushl %ebp
+1 00001824 89e5 movl %esp,%ebp
+3 00001826 83ec10 subl $0x10,%esp
+6 00001829 31c0 xorl %eax,%eax
+8 0000182b c9 leave
+9 0000182c c3 ret
答案 0 :(得分:3)
在完整崩溃报告中,您可以在二进制文件部分中看到用户已加载两个GrowlSafari副本:
0x140c000 - 0x140efff +com.growl.GrowlSafari 1.1.6 (1.1.6) <1E774BDF-5CC5-4876-7C66-380EBFEAF190> /Library/InputManagers/GrowlSafari/GrowlSafariLoader.bundle/Contents/PlugIns/GrowlSafari.bundle/Contents/MacOS/GrowlSafari
0x179d2000 - 0x179d4ff7 +com.growl.GrowlSafari 1.2.1 (1.2.1) <10F1EF69-D655-CCEE-DF3A-1F6C0CF541D3> /Applications/GrowlSafari.app/Contents/Resources/GrowlSafari.bundle/Contents/MacOS/GrowlSafari
我在问题中展示的代码来自1.2.1(但很可能它自1.1.6以来没有改变)并且反汇编是1.2.1。
这可能是问题的原因,特别是因为递归似乎实际上是一个混合的方法(感谢Twitter上的@_karsten_ pointing this out)。
答案 1 :(得分:1)
在某处的尾部调用可能导致一个或多个函数从堆栈跟踪中消失,这当然会使调试变得有趣。
在我的脑海中,我可以想到可能导致这种情况的两种可能情况:
格式字符串是NSString的子类,或者在writeWithFormat()期间有一个类别导致调用writeWithFormat()。自定义日志记录代码有时会这样做 - 编写一些通用的自定义日志记录代码非常容易,这些代码可以很好地回调自身。去过也做过。很多次,可悲的是。
内存中的异常导致递归;腐败的物体或其他东西。
对稻草都有点掌握。发布整个崩溃报告。
捆绑包的两个版本在运行时间内进行了调整...所有投注都关闭,直到崩溃再次面对其中一个捆绑包。我敢打赌这就是问题所在。
我还打赌有一些相关的控制台呕吐。