Mam wielowątkową aplikację, która jest bardzo stabilna na wszystkich moich komputerach testowych i wydaje się stabilna dla prawie każdego z moich użytkowników (w oparciu o brak skarg na awarie). Jednak aplikacja często się zawiesza dla jednego użytkownika, który był na tyle uprzejmy, aby wysyłać raporty o awariach. Wszystkie raporty o awariach (~ 10 kolejnych raportów) wyglądają zasadniczo identycznie:
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
(... więcej tekstu poniżej)
Po pierwsze, spędziłem dużo czasu na badaniu [NSFont fontWithName: size:]. Pomyślałem, że być może czcionki użytkownika zostały w jakiś sposób spieprzone, więc [NSFont fontWithName: size:] żąda czegoś nieistniejącego i z tego powodu zawodzi. Dodałem trochę kodu za pomocą [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask], aby sprawdzić z wyprzedzeniem dostępność czcionek. Niestety, te zmiany nie rozwiązały problemu.
Zauważyłem, że zapomniałem usunąć niektóre punkty przerwania debugowania, w tym _NSLockError, [NSException raise] i objc_exception_throw. Jednak aplikacja została zdecydowanie zbudowana przy użyciu „Release” jako aktywnej konfiguracji kompilacji. Zakładam, że użycie konfiguracji „Release” uniemożliwia ustawienie jakichkolwiek punktów przerwania - ale z drugiej strony nie jestem pewien, jak dokładnie działają punkty przerwania ani czy program musi być uruchamiany z poziomu gdb, aby punkty przerwania miały jakikolwiek efekt.
Moje pytania to: czy pozostawienie ustawionych punktów przerwania może być przyczyną awarii zaobserwowanych przez użytkownika? Jeśli tak, dlaczego punkty przerwania miałyby powodować problem tylko dla tego jednego użytkownika? Jeśli nie, czy ktokolwiek inny miał podobne problemy z [NSFont fontWithName: size:]?
Prawdopodobnie spróbuję po prostu usunąć punkty przerwania i odesłać do użytkownika, ale nie jestem pewien, ile waluty pozostało temu użytkownikowi. Chciałbym też bardziej ogólnie zrozumieć, czy pozostawienie ustawionych punktów przerwania może spowodować problem (gdy aplikacja jest budowana przy użyciu konfiguracji „Release”).
Jest bardzo prawdopodobne, że ten użytkownik ma zainstalowaną uszkodzoną czcionkę. Ślad stosu zdecydowanie potwierdza tę hipotezę, podobnie jak fakt, że wpływa tylko na jednego użytkownika.
W takim przypadku niewiele można zrobić, poza nakłonieniem użytkownika do usunięcia naruszającej czcionki, ponieważ awarie, które występują, mają miejsce głęboko w kodzie Apple.
Spróbuj zachęcić użytkownika do uruchomienia sprawdzania poprawności czcionki w Albumie z czcionkami. Aby to zrobić, uruchom Album z czcionkami, kliknij opcję Wszystkie czcionki na liście źródeł, a następnie wybierz wszystkie wymienione czcionki. Następnie możesz wybrać opcję Sprawdź poprawność czcionek z menu Plik .
źródło
Punkty przerwania nie są zapisywane w pliku binarnym. Istnieje duże prawdopodobieństwo, że ta osoba ma zepsutą instalację systemu operacyjnego. Sprawdź dzienniki konsoli pod kątem komunikatów dyld.
źródło
Miałem ten sam błąd. Z niewyjaśnionych powodów punkt przerwania był odpowiedzialny za zgłoszenie wyjątku EXC_BREAKPOINT . Rozwiązaniem było usunięcie punktu przerwania, a kod działa.
EXC_BREAKPOINT jest rodzajem wyjątku używanego przez debugery. Po ustawieniu punktu przerwania w kodzie kompilator wstawia wyjątek tego typu w kodzie wykonywalnym. Gdy wykonanie osiągnie ten punkt, wyjątek jest zgłaszany i debuger przechwytuje go. Następnie debugger wyświetla kod w wierszu „punkt przerwania”. Tak działają debuggery. Ale w tym przypadku debugger nie obsługuje poprawnie wyjątku i jest przedstawiany jako zwykły błąd wyjątku.
Znalazłem ten błąd dwa razy w życiu:
źródło