2010-04-09 11 views
64

Ho un'applicazione multithread che è molto stabile su tutte le mie macchine di prova e sembra essere stabile per quasi tutti i miei utenti (in base a nessuna lamentela di crash). L'app si arresta spesso in modo anomalo per un utente, che è stato così gentile da inviare rapporti sugli arresti anomali. Tutte le segnalazioni di crash (~ 10 rapporti consecutivi) appaiono sostanzialmente identici:Le eccezioni "EXC_BREAKPOINT (SIGTRAP)" sono causate dal debug dei punti di interruzione?

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 

(.... altro testo segue)

In primo luogo, ho trascorso molto tempo indagando [NSFont fontWithName: formato:]. Ho pensato che forse i caratteri dell'utente erano stati rovinati in qualche modo, così che [NSFont fontWithName: size:] richiedeva qualcosa di inesistente e non funzionante per quel motivo. Ho aggiunto un po 'di codice usando [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] per verificare la disponibilità dei font in anticipo. Purtroppo, queste modifiche non hanno risolto il problema.

Ora ho notato che ho dimenticato di rimuovere alcuni punti di interruzione del debug, tra cui _NSLockError, [NSException raise] e objc_exception_throw. Tuttavia, l'app è stata sicuramente creata utilizzando "Release" come configurazione di build attiva. Presumo che l'utilizzo della configurazione "Release" impedisca l'impostazione di qualsiasi punto di interruzione, ma poi di nuovo non sono sicuro di come funzionano i punti di interruzione o se il programma deve essere eseguito da gdb affinché i punti di interruzione abbiano effetto.

Le mie domande sono: potrei aver lasciato i setpoint di interruzione essere la causa dei crash osservati dall'utente? In tal caso, perché i breakpoint causerebbero un problema solo per questo utente? In caso contrario, qualcun altro ha avuto problemi simili con [NSFont fontWithName: size:]?

Probabilmente cercherò di rimuovere i punti di interruzione e di inviarlo all'utente, ma non sono sicuro di quanta moneta mi sia rimasta con quell'utente. E mi piacerebbe capire più in generale se lasciare il setpoint potrebbe causare un problema (quando l'app è costruita usando la configurazione "Release").

risposta

159

Le eccezioni "EXC_BREAKPOINT (SIGTRAP)" causate dal debug dei punti di interruzione?

No. contrario, in realtà: un SIGTRAP (trappola trace) farà sì che il debugger di rompere (interrupt) il programma, allo stesso modo di un punto di interruzione reale sarebbe. Questo perché il debugger si interrompe sempre in caso di crash e un SIGTRAP (come molti altri signals) è un tipo di arresto anomalo.

I SIGTRAP sono generalmente causati dall'esclusione di NSException, ma non sempre, è anche possibile effettuare direttamente uno raise.

ora ho notato che ho dimenticato di rimuovere alcuni punti di interruzione di debug, tra _NSLockError, [NSException rilancio], e objc_exception_throw.

Questi non sono punti di interruzione. Due di loro sono funzioni e -[NSException raise] è un metodo.

Intendevi impostare i punti di interruzione su tali funzioni e tale metodo?

considera che utilizzando la configurazione "rilascio" impedisce impostazione di qualsiasi breakpoints--

No.

Le configurazioni sono accumulo configurazioni. Influenzano il modo in cui Xcode crea le tue applicazioni.

I punti di interruzione non fanno parte della costruzione; li hai impostati nel debugger. Esiste solo, viene colpito e interrompe il programma solo quando si esegue il programma sotto il debugger.

Poiché non fanno parte della build, non è possibile passare i punti di interruzione a un utente semplicemente assegnando loro il pacchetto dell'app.

Io non sono sicuro esattamente come funzionano i punti di interruzione ...

Quando il programma colpisce il punto di interruzione, le interruzioni di debugger (interrupt) il programma, dopo di che è possibile esaminare lo stato del programma e passo con attenzione in avanti per vedere come il programma va storto

Poiché è il debugger che arresta il programma, i punti di interruzione non hanno alcun effetto quando non si esegue il programma sotto il debugger.

... o se il programma deve essere eseguito da gdb affinché i punti di interruzione abbiano effetto.

Lo fa. I breakpoint del debugger funzionano solo all'interno del debugger.

Le mie domande sono: potrei aver lasciato i setpoint di interruzione essere la causa dei crash osservati dall'utente?

No.

In primo luogo, come è noto, anche se questi punti di interruzione hanno in qualche modo vengono riportati al sistema dell'utente, i punti di interruzione sono efficaci solo nel debugger. Il debugger non può fermarsi su un punto di interruzione se il programma non è in esecuzione nel debugger. L'utente quasi certamente non sta eseguendo la tua app sotto il debugger, soprattutto perché hanno ottenuto un registro di crash.

Anche se hanno finito la vostra applicazione nel debugger con tutti questi punti di interruzione impostato, un punto di interruzione viene colpito solo quando il programma raggiunge quel punto, così uno di questi punti di interruzione poteva sparare solo se voi o cacao chiamato _NSLockError, -[NSException raise], o objc_exception_throw. Arrivare a quel punto non sarebbe la causa del problema, sarebbe un sintomo del problema.

E se si è verificato un arresto anomalo a causa di uno di quelli richiamati, il registro degli arresti anomali avrebbe almeno un nome chiamato. Non è così.

Quindi, questo non era correlato ai tuoi punti di interruzione (diversa macchina, debugger non coinvolto), e non era un'eccezione Cocoa-come ho detto, le eccezioni Cocoa sono una delle cause dei SIGTRAP, ma non sono le uniche uno. Ne hai incontrato uno diverso.

In caso contrario, qualcuno ha avuto problemi simili con [font NSFontWithName: size:]?

Non c'è modo di sapere se i problemi riscontrati sono simili perché è stato tagliato il registro degli arresti anomali. Non sappiamo nulla del contesto in cui si è verificato l'incidente.

L'unica cosa che è buona da ritagliare è la sezione "Immagini binarie", poiché non abbiamo i tuoi bundle dSYM, il che significa che non possiamo usare quella sezione per simboleggiare il registro degli arresti anomali.

Tu, d'altra parte, puoi. Ho scritto an app per questo scopo; inserisci il registro degli arresti anomali e dovrebbe rilevare automaticamente il bundle dSYM (stai mantenendo il bundle dSYM per ogni build di versioni distribuite, giusto?) e ripristina i nomi di funzioni e metodi nello stack trace ovunque appaiano le tue funzioni e i tuoi metodi.

Per ulteriori informazioni, vedere Xcode Debugging Guide.

+2

Wow, grazie per la risposta completa. • "Intendevi impostare i breakpoint su quelle funzioni ..." Sì, questo è ciò che intendevo. • "I breakpoint non fanno parte della build ... Esiste solo, viene colpito e interrompe il programma solo quando si esegue il programma sotto il debugger" Grazie, questo è esattamente ciò che volevo sapere. • "simbolizza il registro di arresto ... Ho scritto un'app per questo scopo" Bella app. Generalmente "simbolico" per pura intuizione - ma la tua app è un modo migliore! • Ho concluso che questo deve avere qualche tipo di problema con il font dell'utente e funzionerà su di esso da quella prospettiva. – Dennis

+4

+1 per Symbolicator. –

1

I punti di interruzione non vengono scritti nel file binario. Le probabilità sono buone che questa persona abbia un'installazione del SO non funzionante. Controllare i log della console per i messaggi dyld.

+0

Grazie per questa rapida risposta! In Google su questo problema ho notato che altri hanno EXC_BREAKPOINTS associati a messaggi dyld, ma i miei registri di arresti anomali non mostrano alcun messaggio di dyld. – Dennis

4

È estremamente probabile che questo utente abbia un carattere corrotto installato. La traccia stack supporta sicuramente quell'ipotesi, così come il fatto che interessa solo un utente.

In questo caso non c'è molto che si possa fare tranne ottenere l'utente di rimuovere il carattere offendente, in quanto gli arresti anomali che avvengono avvengono in profondità nel codice Apple.

Provare a far eseguire all'utente una convalida del font nel Libro Font. Per eseguire questa operazione, avviare Font Book, fare clic su Tutti i font nell'elenco di origine e quindi selezionare tutti i tipi di carattere elencati. È quindi possibile selezionare Validate Fonts dal menu File.

+1

Grazie per questo suggerimento su Font Book - So ben poco di Fonts e in realtà ho avuto un tempo interessante per convalidare i miei font ... Suggerirò all'utente di provare questo. – Dennis

+3

+1 per "ha avuto un tempo interessante per convalidare i miei font" – phlebotinum

1

Ho avuto lo stesso errore. Per una ragione inspiegabile, il punto di interruzione era il responsabile del lancio dell'eccezione EXC_BREAKPOINT. La soluzione era rimuovere il punto di interruzione e quindi il codice funziona.

EXC_BREAKPOINT è un tipo di eccezione utilizzato dai debugger. Quando si imposta un punto di interruzione nel codice, il compilatore inserisce un'eccezione di questo tipo nel codice eseguibile. Quando l'esecuzione raggiunge quel punto, viene lanciata l'eccezione e il debugger la cattura. Quindi il debugger mostra il tuo codice nella riga "breakpoint". Ecco come funzionano i debugger. Ma in questo caso il debugger non gestisce correttamente l'eccezione e viene presentato come un normale errore di eccezione.

Ho trovato questo errore due volte nella mia vita:

  • uno utilizzando Xcode circa un anno fa.
  • l'altro utilizzando Visual C++ circa 15 anni fa.
Problemi correlati