Xcode zeigt nicht die Zeile an, die einen Absturz verursacht

126

Jedes Mal, wenn meine App abstürzt, hebt Xcode den Aufruf von UIApicationMain () in der Funktion main () als die Zeile hervor, die den Absturz verursacht hat. In einigen Fällen war das normal (z. B. Segmentierungsfehler), aber der Absturz, mit dem ich mich befassen möchte, ist ein einfaches SIGABRT mit detaillierten Informationen, die in der Konsole protokolliert werden:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'

Xcode zeigte die Zeile bei älteren SDKs genau richtig an, aber seit ich auf Xocde 4.2 aktualisiert habe, hat sich das geändert. Es ist ziemlich offensichtlich, dass Xcode genau weiß, was den Absturz verursacht hat (oder wissen könnte), aber es zeigt immer noch nicht die tatsächliche Linie. Gibt es eine Lösung oder Problemumgehung dafür?

JonasG
quelle
2
Kompilieren Sie für Release? Wenn ja, setzen Sie das Schema auf Debug.
Epatel
Es kann auch sein, dass xib fehlerhaft ist und das Programm an einer Stelle außerhalb Ihres eigenen Quellcodes abstürzt und somit keine Datei anzeigt. Der Fehler beschreibt ein Problem für einen Wörterbuchschlüssel mit dem Namen "Date"
Epatel
1
Apple sollte mehr Tester einstellen;)
Amr Lotfy

Antworten:

301

Sie sollten auch sicherstellen, dass für alle Ausnahmen Haltepunkte festgelegt sind. Dadurch stoppt Xcode an der Zeile, an der die Ausnahme auftritt. Gehen Sie wie folgt vor [in Xcode 4]:

  1. Klicken Sie im Projektnavigator auf der linken Seite von Xcode auf den Haltepunktnavigator (fast bis zur rechten Seite der oberen Schaltflächenleiste. Das Symbol sieht aus wie ein fetter Pfeil nach rechts).

  2. Klicken Sie unten im Navigator auf die Schaltfläche "+".

  3. Klicken Sie auf "Ausnahme-Haltepunkt hinzufügen".

  4. Ein neuer Haltepunkt wird erstellt. Es sollte nach Bedarf konfiguriert werden, aber Sie können sein Verhalten optimieren.

  5. Führen Sie Ihr Projekt aus und reproduzieren Sie die Ausnahme.

Außerdem haben Sie erwähnt, dass Sie mit einigen Bibliotheken / Frameworks von Drittanbietern verknüpft sind. Wenn die Ausnahme in diesen Frameworks auftritt, wird es Ihnen schwer fallen, da der Code kompiliert wird und Xcode Ihnen die Zeile, die die Ausnahme verursacht hat, nicht anzeigen kann. Wenn dies der Fall ist und Sie sicher sind, dass Sie die Bibliotheken korrekt verwenden, sollten Sie den Betreuern dieser Bibliotheken einen Fehlerbericht vorlegen.

Fuhrmann
quelle
4
Ich bin ein Noob und habe mich fast einen Monat ohne das entwickelt ... das verändert mein Leben.
Jonny Burger
4
Mein Freund hat sich für ein SO-Konto registriert, um diesen Beitrag zu verbessern.
Alex Spencer
1
Dies wird in meinem Buch als halber Arsch auf Äpfeln bezeichnet
ChuckKelly
1
Habe dies getan, kann aber immer noch nicht finden, wo es Länge auf einer Null genannt hat :(
Shereef Marzouk
1
Dies funktioniert, aber der Nachteil ist, dass Details der Ausnahme nicht mehr in der Debug-Konsole ausgegeben werden. So kann ich diesen Haltepunkt ausschalten und Details und Spuren der Ausnahme anzeigen, aber nicht, wo es passiert ist, oder ihn einschalten, um zu sehen, wo es passiert ist, aber nicht mit WARUM. Weiß jemand, wie man beides hat?
Gabriel Jensen
27

Folgen Sie einfach den Anweisungen auf dieser StackOverflow-Antwort:

Zombies aktivieren

Grundsätzlich müssen Sie nur "Zombies aktivieren". Dann sollte Xcode an der Zeile unterbrochen werden, die das Problem verursacht hat.

Geben Sie hier die Bildbeschreibung ein

(Es ist absolut schockierend, dass Xcode dies auch 2017 standardmäßig noch deaktiviert hat. Warum sollten Sie die Zeile, die das Problem verursacht hat, nicht sehen wollen? Und " Zombie-Objekte aktivieren " ?! Wirklich ?! Tun die Xcode-Autoren wirklich glauben, dass dies ein nützlicher Name ist, der für neue Entwickler irgendeinen Sinn ergeben würde? Es ist bedrückend, wie schlecht die Bewertung von Xcode Jahr für Jahr im App Store ist. Niemand hört zu ...)

Mike Gledhill
quelle
6
Xcode ist die schlechteste Programmierumgebung, die ich bisher verwendet habe.
Student
Was ich (als Visual Studio-Entwickler) interessant finde, ist, wie viele Xcode-Entwickler ich getroffen habe, die darauf bestehen, dass Xcode die beste Umgebung ist, die sie jemals verwendet haben. Logisch, freundlich und hilfsbereit .. aber mit ein paar Macken. Selbst jetzt, im November 2019, hat Xcode eine App Store-Bewertung von 3,1, wobei die meisten Leute ihm 5-Sterne oder 1-Sterne geben. Niemand hört zu ...
Mike Gledhill
9

Bearbeiten , um das aktuelle Schema und ermöglicht NSZombieEnabled, MallocStackLoggingund guard malloc. Wenn Ihre App abstürzt, geben Sie dies in die GDB-Konsole ein:

(gdb) info malloc-history 0x543216

Ersetzen Sie 0x543216durch die Adresse des Objekts, das das verursacht hat, NSInvalidArgumentExceptionund es sollte Ihnen eine viel nützlichere Stapelverfolgung geben, die die Zeilen Ihres Codes anzeigt, die den Absturz verursachen.

chown
quelle
1
Ich habe es versucht und es wurde der Fehler ausgegeben: 'info' ist kein gültiger Befehl. Irgendein Rat?
Achi
@EliGregory Stellen Sie sicher, dass Ihr Debugger auf gdb und nicht auf die Standard-lldb eingestellt ist. Sie können es im Menü Schema bearbeiten im Abschnitt Ausführen ändern.
Chown
2

Ich habe dieses Verhalten in stark optimiertem Code gesehen. Das Überprüfen, Optimieren der Optimierungsstufe Ihres Ziels und der Libs von Drittanbietern kann hilfreich sein. (Einstellung der LLVM 3.0-Optimierungsstufe)

Generieren Sie Debug-Symbole?

FluffulousChimp
quelle
Einverstanden. Wenn Sie versuchen zu debuggen, muss die Optimierungsstufe in Ihren Build-Einstellungen auf 0 (Keine Optimierung) gesetzt werden.
Carter
1

Ich habe Code geschrieben, um einen Absturz des Index außerhalb der Grenzen zu generieren. Es folgt die Ausnahme.

2017-01-07 04:02:57.606 testABC[1694:52966] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e85cd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010e2be21e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111
    3   testABC                             0x000000010dce962d -[ViewController ComplexFunction] + 61
    4   testABC                             0x000000010dce95db -[ViewController thirdFunction] + 43
    5   testABC                             0x000000010dce959b -[ViewController secondFunction] + 43
    6   testABC                             0x000000010dce955b -[ViewController firstFinction] + 43
    7   testABC                             0x000000010dce96c2 -[ViewController viewDidAppear:] + 50
    8   UIKit                               0x000000010ee28a6c -[UIViewController _setViewAppearState:isAnimating:] + 945
    9   UIKit                               0x000000010ee2b7da __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42
    10  UIKit                               0x000000010ee29ac4 -[UIViewController _executeAfterAppearanceBlock] + 86
    11  UIKit                               0x000000010ec8d77c _runAfterCACommitDeferredBlocks + 653
    12  UIKit                               0x000000010ec7a273 _cleanUpAfterCAFlushAndRunDeferredBlocks + 566
    13  UIKit                               0x000000010ec9d757 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke_2 + 194
    14  CoreFoundation                      0x000000010e8016ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    15  CoreFoundation                      0x000000010e7e66f4 __CFRunLoopDoBlocks + 356
    16  CoreFoundation                      0x000000010e7e5e65 __CFRunLoopRun + 901
    17  CoreFoundation                      0x000000010e7e5884 CFRunLoopRunSpecific + 420
    18  GraphicsServices                    0x00000001126d9a6f GSEventRunModal + 161
    19  UIKit                               0x000000010ec80c68 UIApplicationMain + 159
    20  testABC                             0x000000010dce99df main + 111
    21  libdyld.dylib                       0x000000011174968d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Wenn Sie die sorgfältig lesen First Throw call stack

0   CoreFoundation              0x000000010e85cd4b __exceptionPreprocess + 171
1   libobjc.A.dylib             0x000000010e2be21e objc_exception_throw + 48

0 and 1 sind die Systemprozesse nach dem Absturz.

 2   CoreFoundation             0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111

2 ist die Zeile, die die Ausnahme verursacht hat.

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3sagt Ihnen, dass ViewControllerKlassenname ( ComplexFunction) und Funktion naem ( ), in der Ausnahme ausgelöst wurde.

AsifHabib
quelle
4
Ähm, okay. Sie haben absolut Recht, aber ist das freundlich? In jeder modernen Entwicklungsumgebung (ab 1990) werden Sie, wenn eine Ausnahme auftritt, an die Linie weitergeleitet, die das Problem verursacht hat. Während Xcode ... nun ... Ihnen eine solche Stapelverfolgung gibt. Auch Turbo Pascal war nicht so veraltet !!!
Mike Gledhill
4
Es ist lächerlich, dass das Unternehmen, das angeblich für die "beste Benutzererfahrung" bekannt ist, nicht erkennt, dass alle Entwickler in den letzten 20 Jahren daran gewöhnt sind, die Zeilennummer zu sehen, bei der eine Ausnahme ausgelöst wird, und NICHT IN ASSEMBLER. Werde ich verrückt Jede Sprache, mit der ich mein ganzes Leben lang gearbeitet habe, gibt Zeilennummern. Sogar C oder C ++.
Mylovemhz