Werden "EXC_BREAKPOINT (SIGTRAP)" - Ausnahmen durch das Debuggen von Haltepunkten verursacht?

82

Ich habe eine Multithread-App, die auf allen meinen Testmaschinen sehr stabil ist und für fast jeden meiner Benutzer stabil zu sein scheint (basierend auf keinen Beschwerden über Abstürze). Die App stürzt jedoch häufig für einen Benutzer ab, der so freundlich war, Absturzberichte zu senden. Alle Absturzberichte (~ 10 aufeinanderfolgende Berichte) sehen im Wesentlichen identisch aus:

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

(.... weiterer Text folgt)

Zuerst habe ich lange nach [NSFont fontWithName: size:] gesucht. Ich nahm an, dass die Schriftarten des Benutzers möglicherweise irgendwie durcheinander waren, so dass [NSFont fontWithName: size:] etwas anforderte, das nicht vorhanden war und aus diesem Grund fehlschlug. Ich habe eine Reihe von Code mit [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] hinzugefügt, um die Verfügbarkeit von Schriftarten im Voraus zu überprüfen. Leider haben diese Änderungen das Problem nicht behoben.

Ich habe jetzt bemerkt, dass ich vergessen habe, einige Debugging-Haltepunkte zu entfernen, einschließlich _NSLockError, [NSException Raise] und objc_exception_throw. Die App wurde jedoch definitiv mit "Release" als aktiver Build-Konfiguration erstellt. Ich gehe davon aus, dass die Verwendung der "Release" -Konfiguration das Setzen von Haltepunkten verhindert. Andererseits bin ich mir nicht sicher, wie Haltepunkte genau funktionieren oder ob das Programm innerhalb von gdb ausgeführt werden muss, damit Haltepunkte wirksam werden.

Meine Fragen sind: Könnte mein Verlassen der festgelegten Haltepunkte die Ursache für die vom Benutzer beobachteten Abstürze sein? Wenn ja, warum würden die Haltepunkte nur für diesen einen Benutzer ein Problem verursachen? Wenn nicht, hatte jemand andere ähnliche Probleme mit [NSFont fontWithName: size:]?

Ich werde wahrscheinlich nur versuchen, die Haltepunkte zu entfernen und an den Benutzer zurückzusenden, aber ich bin mir nicht sicher, wie viel Währung ich noch bei diesem Benutzer habe. Und ich möchte allgemeiner verstehen, ob das Verlassen der festgelegten Haltepunkte möglicherweise zu einem Problem führen kann (wenn die App mit der Konfiguration "Release" erstellt wird).

Dennis
quelle

Antworten:

187

Werden "EXC_BREAKPOINT (SIGTRAP)" - Ausnahmen durch das Debuggen von Haltepunkten verursacht?

Nein. Eigentlich anders herum: Ein SIGTRAP (Trace Trap) bewirkt, dass der Debugger Ihr Programm unterbricht (unterbricht), genau wie ein tatsächlicher Haltepunkt. Dies liegt jedoch daran, dass der Debugger bei einem Absturz immer unterbrochen wird und ein SIGTRAP (wie mehrere andere Signale ) eine Art von Absturz ist.

SIGTRAPs werden im Allgemeinen durch das Auslösen von NSExceptions verursacht, aber nicht immer - es ist sogar möglich, direkt zu erhöhen selbst eine Beurteilung.

Ich habe jetzt bemerkt, dass ich vergessen habe, einige Debugging-Haltepunkte zu entfernen, einschließlich _NSLockError, [NSException Raise] und objc_exception_throw.

Das sind keine Haltepunkte. Zwei davon sind Funktionen und-[NSException raise] eine Methode.

Meinten Sie, Sie setzen Haltepunkte auf diese Funktionen und diese Methode festgelegt?

Ich gehe davon aus, dass die Verwendung der "Release" -Konfiguration das Setzen von Haltepunkten verhindert.

Nein.

Die Konfigurationen sind bauen Konfigurationen. Sie wirken sich darauf aus, wie Xcode Ihre Anwendungen erstellt.

Haltepunkte sind nicht Teil des Builds. Sie setzen sie im Debugger. Sie existieren nur, werden nur getroffen und stoppen Ihr Programm nur, wenn Sie Ihr Programm unter dem Debugger ausführen.

Da sie nicht Teil des Builds sind, ist es nicht möglich, Ihre Haltepunkte an einen Benutzer zu übergeben, indem Sie ihm einfach das App-Bundle geben.

Ich bin mir nicht sicher, wie genau Haltepunkte funktionieren ...

Wenn Ihr Programm den Haltepunkt erreicht, unterbricht (unterbricht) der Debugger Ihr Programm, woraufhin Sie den Status des Programms überprüfen und vorsichtig vorwärts gehen können, um festzustellen, wie das Programm schief geht.

Da es der Debugger ist, der Ihr Programm stoppt, haben Haltepunkte keine Auswirkung, wenn Sie Ihr Programm nicht unter dem Debugger ausführen.

… Oder ob das Programm innerhalb von gdb ausgeführt werden muss, damit Haltepunkte Wirkung zeigen.

Es tut. Debugger-Haltepunkte funktionieren nur innerhalb des Debuggers.

Meine Fragen sind: Könnte mein Verlassen der festgelegten Haltepunkte die Ursache für die vom Benutzer beobachteten Abstürze sein?

Nein.

Erstens sind Haltepunkte, wie bereits erwähnt, nur im Debugger wirksam, selbst wenn diese Haltepunkte irgendwie auf das System des Benutzers übertragen wurden. Der Debugger kann nicht an einem Haltepunkt anhalten, wenn Ihr Programm nicht unter dem Debugger ausgeführt wird. Der Benutzer führt Ihre App mit ziemlicher Sicherheit nicht unter dem Debugger aus, zumal er ein Absturzprotokoll hat.

Selbst wenn Ihre App unter dem Debugger ausgeführt wurde und alle diese Haltepunkte festgelegt wurden, wird ein Haltepunkt nur erreicht, wenn Ihr Programm diesen Punkt erreicht, sodass einer dieser Haltepunkte nur ausgelöst werden kann, wenn Sie oder Cocoa aufgerufen _NSLockErrorhaben -[NSException raise], oder objc_exception_throw. An diesen Punkt zu gelangen, wäre nicht die Ursache des Problems, sondern ein Symptom des Problems.

Und wenn Sie aufgrund eines Aufrufs abgestürzt wären, würde in Ihrem Absturzprotokoll mindestens einer von ihnen benannt sein. Das tut es nicht.

Dies hing also nicht mit Ihren Haltepunkten zusammen (anderer Computer, Debugger nicht beteiligt), und es war keine Cocoa-Ausnahme - wie ich bereits erwähnte, sind Cocoa-Ausnahmen eine Ursache für SIGTRAPs, aber sie sind nicht die einzige. Sie sind auf einen anderen gestoßen.

Wenn nicht, hatte jemand andere ähnliche Probleme mit [NSFont fontWithName: size:]?

Wir können auf keinen Fall feststellen, ob ähnliche Probleme ähnlich sind, da Sie das Absturzprotokoll abgeschnitten haben. Wir wissen nichts darüber, in welchem ​​Kontext der Absturz passiert ist.

Das einzige, was gut ausgeschnitten werden kann, ist der Abschnitt "Binäre Bilder", da wir Ihre dSYM-Bundles nicht haben. Dies bedeutet, dass wir diesen Abschnitt nicht als Symbol für das Absturzprotokoll verwenden können.

Sie können andererseits. Zu diesem Zweck habe ich eine App geschrieben . Wenn Sie das Absturzprotokoll einspeisen, sollte es das dSYM-Bundle automatisch erkennen (Sie behalten das dSYM-Bundle für jeden von Ihnen verteilten Release-Build bei, oder?) und Ihre Funktions- und Methodennamen in der Stapelverfolgung wiederherstellen, wo immer Ihre Funktionen und Methoden angezeigt werden.

Weitere Informationen finden Sie im Xcode-Debugging-Handbuch .

Peter Hosey
quelle
3
Wow, danke für die umfassende Antwort. • "Meinten Sie, Sie haben Haltepunkte für diese Funktionen festgelegt ..." Ja, das habe ich gemeint. • "Haltepunkte sind nicht Teil des Builds ... Sie existieren nur, werden nur getroffen und stoppen Ihr Programm nur, wenn Sie Ihr Programm unter dem Debugger ausführen." Danke, genau das wollte ich wissen. • "symbolisiere das Absturzprotokoll ... Ich habe eine App für diesen Zweck geschrieben" Schöne App. Ich "symbolisiere" im Allgemeinen durch reine Intuition - aber Ihre App ist ein besserer Weg! • Ich bin zu dem Schluss gekommen, dass dies ein Problem mit der Schriftart des Benutzers sein muss und aus dieser Perspektive daran arbeiten wird.
Dennis
7

Es ist sehr wahrscheinlich, dass auf diesem Benutzer eine beschädigte Schriftart installiert ist. Die Stapelverfolgung unterstützt diese Hypothese definitiv, ebenso wie die Tatsache, dass sie nur einen Benutzer betrifft.

In diesem Fall können Sie nicht viel tun, außer den Benutzer dazu zu bringen, die fehlerhafte Schriftart zu entfernen, da die auftretenden Abstürze tief im Apple-Code stattfinden.

Versuchen Sie, den Benutzer dazu zu bringen, eine Schriftüberprüfung in Font Book durchzuführen. Starten Sie dazu das Schriftbuch , klicken Sie in der Quellliste auf Alle Schriftarten und wählen Sie dann alle aufgelisteten Schriftarten aus. Anschließend können Sie im Menü Datei die Option Schriftarten validieren auswählen .

Rob Keniger
quelle
1
Vielen Dank für diesen Tipp zu Font Book. Ich weiß sehr wenig über Fonts und hatte tatsächlich eine interessante Zeit, meine eigenen Fonts zu validieren. Ich werde dem Benutzer vorschlagen, dies zu versuchen.
Dennis
0

Haltepunkte werden nicht in die Binärdatei geschrieben. Die Chancen stehen gut, dass diese Person eine fehlerhafte Betriebssysteminstallation hat. Überprüfen Sie die Konsolenprotokolle auf Dyld-Nachrichten.

Azeem.Butt
quelle
Danke für diese schnelle Antwort! Beim Googeln um dieses Problem habe ich festgestellt, dass andere EXC_BREAKPOINTS mit dyld-Nachrichten verknüpft haben - aber meine Absturzprotokolle zeigen keine Nachrichten von dyld an.
Dennis
0

Ich hatte den gleichen Fehler. Aus einem unerklärlichen Grund war der Haltepunkt für das Auslösen der EXC_BREAKPOINT- Ausnahme verantwortlich. Die Lösung bestand darin, den Haltepunkt zu entfernen, und dann funktioniert der Code.

EXC_BREAKPOINT ist eine Art von Ausnahme, die Debugger verwenden. Wenn Sie in Ihrem Code einen Haltepunkt festlegen, fügt der Compiler eine Ausnahme dieses Typs in den ausführbaren Code ein. Wenn die Ausführung diesen Punkt erreicht, wird die Ausnahme ausgelöst und der Debugger fängt sie ab. Dann zeigt der Debugger Ihren Code in der Zeile "Haltepunkt". So funktionieren Debugger. In diesem Fall behandelt der Debugger die Ausnahme jedoch nicht korrekt und wird als regulärer Ausnahmefehler angezeigt.

Ich habe diesen Fehler zweimal in meinem Leben gefunden:

  • eine mit Xcode vor etwa einem Jahr.
  • die andere mit Visual C ++ vor etwa 15 Jahren.
Veladan
quelle
Es ist seltsam, dass ich diesen Fehler ohne Haltepunkte bekommen habe.
Kelin
Ich sage nicht, dass dieser Fehler nur bei Haltepunkten auftritt: EXC_BREAKPOINT kann aus mehreren Gründen auftreten. Was ich erkläre, sind zwei sehr seltene Fälle, in denen ein Haltepunkt eine nicht behandelte Ausnahme generiert.
Veladan