我有一个多线程的应用程序,在我的所有测试机器上都非常稳定,并且对于我的几乎所有用户来说似乎都很稳定(基于没有崩溃的抱怨)。该应用程序经常为一个用户崩溃,他们很友好地发送崩溃报告。所有崩溃报告(约10个连续报告)看起来基本相同:
Date/Time: 2010-04-06 11:44:56.106 -0700
OS Version: Mac OS X 10.6.3 (10D573)
Report Version: 6
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 com.apple.CoreFoundation 0x90ab98d4 __CFBasicHashRehash + 3348
1 com.apple.CoreFoundation 0x90adf610 CFBasicHashRemoveValue + 1264
2 com.apple.CoreText 0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126
3 com.apple.CoreText 0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115
4 com.apple.CoreText 0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40
5 com.apple.CoreText 0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135
6 com.apple.AppKit 0x961f5952 __NSFontFactoryWithName + 904
7 com.apple.AppKit 0x961f54f0 +[NSFont fontWithName:size:] + 39
(....更多文字如下)
首先,我花了很长时间调查[NSFont fontWithName:size:]。我想,也许用户的字体被搞砸了,所以[NSFont fontWithName:size:]正在请求一些不存在的东西并因此失败。我使用[[NSFontManager sharedFontManager] availableFontNamesWithTraits:NSItalicFontMask]添加了一堆代码,以提前检查字体可用性。可悲的是,这些变化并没有解决问题。
我现在已经注意到我忘记删除一些调试断点,包括_NSLockError,[NSException raise]和objc_exception_throw。但是,应用程序绝对是使用“Release”作为活动构建配置构建的。我假设使用“Release”配置可以防止设置任何断点 - 但是我又不确定断点是如何工作的,或者是否需要从gdb中为断点运行程序才能产生任何影响。
我的问题是:我的离开断点是否可以成为用户观察到的崩溃的原因?如果是这样,为什么断点只会导致这个用户出现问题?如果没有,有没有其他人与[NSFont fontWithName:size:]?
有类似的问题我可能会尝试删除断点并发回给用户,但我不确定该用户剩下多少货币。我想更一般地了解是否设置断点可能会导致问题(当使用“Release”配置构建应用程序时)。
答案 0 :(得分:175)
调试断点导致“EXC_BREAKPOINT(SIGTRAP)”异常吗?
没有。其他方面,实际上:SIGTRAP(跟踪陷阱)将导致调试器中断(中断)您的程序,就像实际断点一样。但那是因为调试器总是在崩溃时中断,而SIGTRAP(就像其他几个signals)是一种崩溃。
SIGTRAP通常是由抛出NSExceptions引起的,但并非总是如此 - 甚至可以直接raise一个人自己。
我现在注意到我忘记删除一些调试断点,包括_NSLockError,[NSException raise]和objc_exception_throw。
这些不是断点。其中两个是函数,-[NSException raise]
是一个方法。
你的意思是你设置了 那些函数和那个方法的断点吗?
我认为使用“Release”配置可以防止设置任何断点 -
没有
配置是 build 配置。它们会影响Xcode构建应用程序的方式。
断点不是构建的一部分;你在调试器中设置它们。它们只存在,只会被命中,只有在调试器下运行程序时才会停止程序。
由于它们不是构建的一部分,因此无法通过向用户提供应用程序包来将断点传递给用户。
我不确定断点是如何工作的......
当程序到达断点时,调试器会中断(中断)程序,然后您可以检查程序的状态并仔细检查程序是否出错。
由于调试器是停止程序的,因此当您未在调试器下运行程序时,断点无效。
...或者是否需要在gdb内运行程序以使断点产生任何影响。
确实如此。调试器断点仅在调试器中工作。
我的问题是:我的离开断点是否可以成为用户观察到的崩溃的原因?
没有
首先,如上所述,即使这些断点以某种方式转移到用户的系统,断点也仅在调试器中有效。如果您的程序未在调试器下运行,则调试器无法在断点处停止。用户几乎肯定没有在调试器下运行你的应用程序,特别是因为他们收到了崩溃日志。
即使他们确实在设置了所有这些断点的调试器下运行您的应用程序,只有当您的程序到达该点时才会触发断点,因此只有当您或Cocoa调用_NSLockError
时才会触发其中一个断点,-[NSException raise]
或objc_exception_throw
。达到这一点不是问题的原因,而是问题的症状。
如果由于其中一个被调用而导致崩溃,那么崩溃日志中至少会有一个命名。它没有。
所以,这与您的断点无关(不同的机器,调试器没有涉及),并且它不是Cocoa异常 - 正如我所提到的,Cocoa异常是SIGTRAP的一个原因,但它们不是唯一的。你遇到了另一个。
如果没有,还有其他人与[NSFont fontWithName:size:]有类似的问题吗?
我们无法判断我们遇到的任何问题是否相似,因为您切断了崩溃日志。我们对崩溃发生的背景一无所知。
唯一可以删除的是“二进制图像”部分,因为我们没有你的dSYM包,这意味着我们不能使用该部分来表示崩溃日志。
另一方面,你可以。为此我写了an app;将崩溃日志提供给它,它应该自动检测dSYM包(你为每个Release发布版本保留dSYM包,对吗?)并将函数和方法名称恢复到堆栈跟踪中,无论你的函数和方法出现在哪里。有关详细信息,请参阅Xcode Debugging Guide。
答案 1 :(得分:5)
此用户极有可能安装了损坏的字体。堆栈跟踪肯定支持该假设,因为它只影响一个用户。
除非让用户删除有问题的字体,否则在这种情况下你无能为力,因为发生的崩溃发生在Apple的代码深处。
尝试让用户在Font Book中运行字体验证。要执行此操作,请启动字体簿,单击源列表中的所有字体,然后选择所有列出的字体。然后,您可以从文件菜单中选择验证字体。
答案 2 :(得分:0)
断点不会写入二进制文件。这个人的操作系统安装损坏的可能性很大。检查控制台日志中的dyld消息。
答案 3 :(得分:0)
我有同样的错误。由于无法解释的原因,断点是抛出 EXC_BREAKPOINT 异常的原因。解决方案是删除断点,然后代码工作。
EXC_BREAKPOINT 是调试器使用的一种异常。在代码中设置断点时,编译器会在可执行代码中插入此类型的异常。当执行到达该点时,抛出异常并且调试器捕获它。然后调试器在“breakpointed”行显示您的代码。这是调试器的工作方式。但在这种情况下,调试器不能正确处理异常,并表示为常规异常错误。
我生命中曾两次发现这个错误: