2014-03-07 13 views
6

Das ist also einige Male in verschiedenen Projekten passiert. Ich werde meine App in Xcode debuggen, wenn Xcode bei einem Fehler bricht. Nachdem ich es angesehen hatte, traf ich Step Over oder Continue ... und es würde nichts bewirken. Genauer gesagt, es handelte so, als wäre es getreten, aber es ging nirgendwohin. Dies kann beliebig oft wiederholt werden, soweit ich das beurteilen kann. Ein Grund, warum dies problematisch ist, ist, dass es mir nie das Crash-Protokoll gibt, weil es niemals abstürzt. Ich erhalte nur das Absturzprotokoll, wenn die App abstürzt und nicht geblockt wird (was bedeutet, dass ich es durch Crittercism oder durch Überprüfung der Geräteprotokolle bekommen muss).Xcode wird den Absturz nicht überspringen

Jeder sieht das vorher, und/oder wissen, warum es das tut? Ich habe das nirgendwo anders erwähnt, aber es ist mir in mehreren Projekten passiert.

Zum Beispiel in einem Projekt, das wir SocketRocket verwenden, und jeder einmal in eine Weile (für eine as-of-noch unbekannten Gründen) in SRWebSocket.m in der folgenden Methode abstürzt:

- (void)main; 
{ 
    @autoreleasepool { 
     _runLoop = [NSRunLoop currentRunLoop]; 
     dispatch_group_leave(_waitGroup); 

     NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate distantFuture] interval:0.0 target:nil selector:nil userInfo:nil repeats:NO]; 
     [_runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; 

     int i = 0; 

     while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) { 
      NSLog(@"_runLoop %i %@", i++, [NSDate date]); 
     } 
     assert(NO); 
    } 
} 

Es stürzt auf der while Linie ab. (Ich habe übrigens die NSLog-Zeile hinzugefügt). Wenn ich Continue oder Step Over drücke, flackert die Linienanzeige kurz und erscheint dann wieder in derselben Zeile. Beachten Sie, dass die NSLog-Zeile nicht fortgesetzt wird und überhaupt nichts in die Konsole geschrieben wird. Ich versuche gerade noch, es wieder zum Absturz zu bringen (dieser Absturz ist ziemlich unberechenbar), aber wenn ich mich richtig erinnere, sagt der Zeilenanzeiger EXC_BAD_ACCESS, wahrscheinlich ein vorzeitig freigegebenes Objekt.

+0

Sind Sie sicher, dass Sie etwas nicht verpassen? Vielleicht etwas in die Konsole geschrieben? – ThomasW

+0

@ThomasW Nein, das ist das Problem - nichts wird auf die Konsole geschrieben, es bricht nicht ab, es bricht nur dort und wird nicht weiter gehen. – Erhannis

+0

Es stoppt auch nicht an einem Haltepunkt? Vielleicht haben Sie einen Breakpoint auf Ausnahmen gesetzt? – ThomasW

Antwort

1

Ein ObjC out of range error führt zum Werfen einer ObjC-Ausnahme, die - falls nicht abgefangen - zu einem Abbruch führt. Ein Abbruch erzeugt nur ein BSD-Signal (SIGKILL). Der Debugger kann leicht an den Prozess übergeben, so dass er auf natürliche Weise davon abstürzen kann.

EXC_BAD_ACCESS und EXC_BAD_INSTRUCTION sind lustige Ausnahmen, da sie zuerst auf der Mach-Seite des Betriebssystems kommen. Um richtig verbreitet zu werden, sollten sie nativ als Mach-Ausnahme gehandhabt werden, wenn es einen Handler für sie gibt, und wenn nicht, sollten sie an einen System-Handler übergeben werden, der sie in die äquivalente BSD-Ausnahme (SIGSEGV) verwandelt, an die dann weitergegeben wird der BSD-Signal-Handler und das führt schließlich dazu, dass Ihr Programm beendet wird.

Es gibt einen seit langem bestehenden Fehler in den Kernel-Schnittstellen des Debuggers, der es dem Debugger unmöglich macht, diesen kleinen Tanz von außen richtig zu beeinflussen. Wenn du also eine EXC_BAD_ACCESS bekommst, bist du da ziemlich festgefahren. Meistens spielt das keine Rolle, Ihr Programm würde sich einfach umdrehen und sowieso sterben. Sie würden wirklich keinen Einblick in Ihren Absturz bekommen, wenn Sie es sehen.

Es spielt nur eine Rolle, wenn Sie einen SIGSEGV-Handler installiert haben und debuggen möchten. Das war auf MacOS X für ein Jahrzehnt oder mehr hart. Glücklicherweise müssen nur sehr wenige Leute das tun ...

+0

Danke; Das klingt nach einer vernünftigen Erklärung. Es wäre jedoch praktisch, einen protokollierten Stack-Trace (usw.) wie üblich zu haben - eine Idee, wenn Sie die Ausnahme erzwingen können, um protokolliert zu werden? – Erhannis

+0

Sprachbasierte Ausnahmen benötigen eine spezielle Behandlung, da sie das Programm nicht beenden, bis die Ausnahme an die äußersten Handler weitergegeben wurde. Der Ursprung der Ausnahme ist also verloren. Das ist bei EXC_BAD_ACCESS usw. nicht so der Fall. Wenn Ihr Programm im Debugger ausgeführt wird, wird es an der Stelle der Ausnahme stoppen, und Sie können "bt" und andere Debugger-Befehle verwenden, um die Ausnahme zu protokollieren, da Sie wird an der Stelle der Ausnahme gestoppt. Andernfalls wird ein Crash-Protokoll erstellt. –

3

Sie verpassen den Punkt von Step Over. Wenn Sie eine Zeile überschreiten, sagen Sie, dass Sie die aktuelle Zeile ausführen und zur nächsten sichtbaren Zeile wechseln, unabhängig davon, ob die aktuelle Zeile eine andere Prozedur aufruft.

Wenn der Code an irgendeinem Punkt abstürzt, können Sie keine Codezeilen mehr ausführen.

+0

Ich weiß. Aber ich glaube, es soll den Absturz beenden und mir die Stapelspur geben, usw. - Ich erinnere mich, dass das für andere Abstürze gemacht wurde. Manchmal bleibt es jedoch nur in dieser Zeile hängen. – Erhannis

+0

Können Sie Ihrer Frage die betroffenen Zeilen und alle Nachrichten, die Sie erhalten, hinzufügen? Ohne das ist es schwer zu sagen, was konkret passiert. – woz

+0

Sie sagen also "EXC_BAD_ACCESS', wahrscheinlich ein vorzeitig freigegebenes Objekt." Das ist dein Fehler und die Ursache. Sobald ein Absturz auftritt, wird nichts anderes mehr ausgeführt. – woz

0

Zu den vorherigen Antworten hinzufügen; Beim Debuggen und EXC_BAD_ACCESS kann es manchmal helfen, "Zombie-Objekte aktivieren" in Ihrem Schema. Wenn Sie auf ein Objekt zugreifen, für das die Zuweisung aufgehoben wurde, werden Ihnen Zombie-Objekte mitteilen, an welchem ​​Objekt Sie nicht versucht haben, einen Anruf auszuführen, und die Methode, die Sie aufrufen wollten.

Verwandte Themen