2010-04-09 164 views
64

我有一個多線程的應用程序,它在我的所有測試機器上都非常穩定,似乎對我的幾乎每個用戶都是穩定的(基於沒有崩潰的抱怨)。但是,該應用程序經常爲一個用戶崩潰,但是,這位用戶非常友好,可以發送崩潰報告。所有崩潰報告(〜10個連續報道)外觀基本相同:調試斷點是否導致「EXC_BREAKPOINT(SIGTRAP)」異常?

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:大小:]。我想,也許用戶的字體被搞亂了,所以[NSFont fontWithName:size:]請求的東西不存在,並因此失敗。我使用[[NSFontManager sharedFontManager] availableFontNamesWithTraits:NSItalicFontMask]添加了一堆代碼,以提前檢查字體可用性。可悲的是,這些變化並沒有解決問題。

我現在已經注意到,我忘了刪除一些調試斷點,包括_NSLockError,[NSException raise]和objc_exception_throw。但是,該應用程序絕對是使用「發佈」作爲活動構建配置構建的。我假定使用「Release」配置可以防止設置任何斷點 - 但是我不能確定斷點究竟是如何工作的,或者是否需要從gdb中運行程序以使斷點產生任何效果。

我的問題是:我可以離開設置的斷點是用戶觀察到的崩潰的原因嗎?如果是這樣,爲什麼斷點只會爲這個用戶造成問題?如果沒有,還有其他人有與[NSFont fontWithName:size:]類似的問題?

我可能會嘗試刪除斷點併發送回用戶,但我不確定該用戶剩下多少貨幣。我希望更普遍地理解是否留下設置的斷點可能會導致問題(當應用程序使用「釋放」配置構建時)。

回答

159

由調試斷點引起「EXC_BREAKPOINT(SIGTRAP)」異常嗎?

其他的方法,實際上:一個SIGTRAP(跟蹤陷阱)將導致調試器中斷(中斷)程序,就像實際斷點一樣。但那是因爲調試器總是在崩潰時崩潰,SIGTRAP(像其他幾個signals)是一種崩潰。

SIGTRAPs通常是由NSExceptions被拋出引起的,但並非總是如此 - 甚至可以直接自己創建一個raise

我已經注意到,我忘記刪除一些調試斷點,包括_NSLockError,[NSException raise]和objc_exception_throw。

那些不是斷點。其中兩個是功能和-[NSException raise]是一種方法。

你是不是說你設置了斷點那些函數和那個方法?

我假定使用 「釋放」 構造防止任何breakpoints--

號的設定

所有配置構建配置。它們影響Xcode如何構建您的應用程序。

斷點不是構建的一部分;你在調試器中設置它們。它們只存在,只有被調用,並且只有在調試器下運行你的程序時才停止你的程序。

因爲它們不是構建的一部分,所以不可能僅通過向用戶提供應用程序包來將斷點傳遞給用戶。

我不知道斷點究竟是如何工作的?

當程序到達斷點,調試中斷(中斷)你的程序,於是你可以檢查程序的狀態,仔細踏前一步看程序如何出錯。

因爲它是停止程序的調試器,所以當您不在調試器下運行程序時,斷點不起作用。

...或者程序是否需要從gdb中運行以獲得有效的斷點。

它的確如此。調試器斷點只能在調試器內工作。

我的問題是:我可以離開設置的斷點是用戶觀察到崩潰的原因嗎?

首先,如上所述,即使這些斷點沒辦法把結轉到用戶的系統,斷點只在調試器有效。如果您的程序沒有在調試器下運行,調試器無法停止在斷點上。用戶幾乎肯定不會在調試器下運行您的應用程序,尤其是因爲他們得到了崩潰日誌。

即使他們沒有在調試器下所有這些斷點設置,當你的程序達到這一點斷點只命中運行你的應用程序,這些斷點所以人們只能火災,如果你或可可叫_NSLockError-[NSException raise],或objc_exception_throw。到達這一點不會是問題的原因,它會成爲問題的症狀。

而且,如果您因其中一個被調用而崩潰,您的崩潰日誌中至少會有一個命名。它沒有。因此,這與您的斷點(不涉及不同的機器,調試器)無關,並且它不是Cocoa異常 - 正如我所提到的,Cocoa異常是SIGTRAPs的一個原因,但它們不是唯一的一。你遇到了另一個。

如果不是,還有其他人有與[NSFont fontWithName:size:]類似的問題?

我們無法判斷我們所遇到的任何問題是否因爲您切斷了崩潰日誌而相似。我們對發生崩潰的背景一無所知。

由於我們沒有dSYM捆綁包,因此我們無法使用該部分以表示崩潰日誌。

另一方面,你可以。我爲此寫了an app;將崩潰日誌提供給它,並且它應該自動檢測dSYM軟件包(對於您發佈的每個發佈版本,您都保留dSYM軟件包,對嗎?),並將函數和方法名稱恢復到您的函數和方法出現的堆棧跟蹤中。

欲瞭解更多信息,請參閱Xcode Debugging Guide

+2

哇,謝謝你的全面答案。 •「你的意思是你設置了這些功能的斷點......」 是的,這就是我的意思。 「 •」斷點不是構建的一部分......它們只存在,只能被擊中,並且只能在調試器下運行程序時停止程序「 謝謝,這正是我想知道的。 •「象徵性的崩潰日誌...我爲此寫了一個應用程序」 好的應用程序。我通常憑藉純粹的直覺「象徵」 - 但你的應​​用程序是更好的方式! •我已經得出結論,這必須與用戶的字體有關的某種問題,並從該角度來處理它。 – Dennis 2010-04-11 00:22:06

+4

符號符號+1。 – 2012-03-09 10:09:51

1

斷點不寫入二進制文件。這個人的操作系統安裝失敗的可能性很大。檢查控制檯日誌中的dyld消息。

+0

感謝您的快速回答!在谷歌搜索這個問題,我注意到其他人有與dyld消息相關的EXC_BREAKPOINTS - 但我的崩潰日誌不顯示任何來自dyld的消息。 – Dennis 2010-04-10 23:32:26

4

該用戶極有可能安裝了損壞的字體。堆棧跟蹤肯定支持該假設,因爲它隻影響一個用戶。

在這種情況下,除了讓用戶刪除違規字體外,沒有太多可以做的事情,因爲發生的崩潰事件發生在Apple的代碼中。

嘗試讓用戶在字體書中運行字體驗證。爲此,請啓動Font Book,在源列表中單擊All Fonts,然後選擇所有列出的字體。然後,您可以從文件菜單中選擇驗證字體

+1

感謝關於字體書的這篇技巧 - 我對字體知之甚少,實際上有一個有趣的時間來驗證我自己的字體......我會建議用戶試試這個。 – Dennis 2010-04-10 23:33:43

+3

+1「有一個有趣的時間驗證我自己的字體」 – phlebotinum 2012-03-01 17:08:55

1

我有同樣的錯誤。由於無法解釋的原因,斷點是拋出EXC_BREAKPOINT異常的責任。解決方案是刪除斷點,然後代碼工作。

EXC_BREAKPOINT是一種調試器使用的異常。在代碼中設置斷點時,編譯器會在可執行代碼中插入此類型的異常。當執行到達那個點時,拋出異常並且調試器捕獲它。然後調試器在「breakpointed」行顯示你的代碼。這是調試器的工作原理。但是在這種情況下,調試器不能正確處理異常,並且顯示爲常規異常錯誤。

我發現這個錯誤在我生命中兩次:

  • 一個使用大約一年前的Xcode。
  • 約15年前使用Visual C++的其他人。