Ich programmiere eine Anwendung in Objective-C und erhalte folgende Fehlermeldung:
MyApp (2121,0xb0185000) malloc: *** Fehler für Objekt 0x1068310: double free
*** Setzen Sie einen Haltepunkt in malloc_error_break zum Debuggen
Es passiert, wenn ich einen NSAutoreleasePool veröffentliche und nicht herausfinden kann, welches Objekt ich zweimal freigebe.
Wie setze ich seinen Haltepunkt?
Gibt es eine Möglichkeit zu wissen, was dieses "Objekt 0x1068310" ist?
Antworten:
Sie werden herausfinden, was das Objekt ist, wenn Sie den Debugger einbrechen. Schauen Sie einfach im Call Stack nach und Sie werden feststellen, wo Sie ihn freigeben. Das wird Ihnen sagen, um welches Objekt es sich handelt.
Der einfachste Weg, den Haltepunkt festzulegen, ist:
quelle
Wenn ein Objekt "doppelt freigegeben" wird, ist die häufigste Ursache, dass Sie (unnötigerweise) ein automatisch freigegebenes Objekt freigeben. Es wird später automatisch freigegeben, wenn der enthaltende Autorelease-Pool geleert wird.
Ich habe festgestellt, dass der beste Weg, um die zusätzliche Version aufzuspüren, darin besteht, die Umgebungsvariable NSZombieEnabled für die betroffene ausführbare Datei in Xcode zu verwenden. Eine kurze Übersicht über die Verwendung finden Sie auf dieser CocoaDev-Wiki-Seite . (Zusätzlich zu dieser Seite hat Apple einige unglaublich undurchsichtige, aber nützliche Tipps zum Debuggen von Code in Xcode dokumentiert, von denen einige meinen Speck mehr als ein paar Mal gespeichert haben. Ich empfehle, diesen technischen Hinweis unter developer.apple.com - Link zu lesen springt zum Abschnitt über das Framework der Cocoa Foundation).
Bearbeiten: Sie können das fehlerhafte Objekt häufig im Xcode-Debugger aufspüren, aber es ist oft viel einfacher, wenn Sie Instrumente verwenden, um Sie zu unterstützen. Wählen Sie in Xcode Ausführen → Mit Leistungstool beginnen → Objektzuordnungen, und Sie sollten in der Lage sein, das fehlerhafte Objekt bis zu dem Ort zurückzuverfolgen, an dem es erstellt wurde. (Dies funktioniert am besten, wenn Sie Zombies wie oben beschrieben aktiviert haben.) Hinweis: Snow Leopard fügt Instrumenten ein Zombies-Tool hinzu, auf das Sie auch über das Menü "Ausführen" zugreifen können. Könnte allein die 29 Dollar wert sein! ;-);
Es gibt hier auch eine verwandte SO-Frage .
quelle
Ich möchte nur meine Erfahrung zusätzlich zur Antwort von Quinn Taylor hinzufügen.
In einer meiner Apps muss ich Daten analysieren und in Kerndatenobjekten speichern und diese Objekte später in den Ansichten anzeigen lassen. Tatsächlich funktioniert die App einwandfrei und stürzt überhaupt nicht ab, bis ich mehrmals versucht habe, einen Stresstest zum Hin- und Herbewegen durchzuführen und mehrere Ansichten so schnell wie möglich zu öffnen. Die App stürzt mit der obigen Meldung ab.
Ich habe alle Methoden ausprobiert, die Quinn in seiner Antwort vorgeschlagen hat, und konnte immer noch nicht herausfinden, wo die genaue Ursache lag.
Ich habe NSZombieEnabled = YES und NSStackLogging = YES festgelegt und die Befehlsshell malloc_history ausgeführt, um herauszufinden, warum, aber immer noch kein Glück. Es wird immer darauf hingewiesen, wo ich die Daten in Kerndatenobjekten speichere. Tatsächlich habe ich die tausendfach freigegebenen Objekte dort tausendmal überprüft, nichts Seltsames.
Das Ausführen von Instrumenten mit verschiedenen Tools (Zuordnungen, Lecks usw.) hat immer noch nicht geholfen. Aktivieren Sie die Wache Malloc hat noch nichts.
Letzte Rettung: Ich habe versucht, zu den Ansichten zurückzukehren, in denen die Objekte aus Core Data entnommen wurden, und eine Aufbewahrungsnachricht an alle diese Objekte gesendet und diese Änderungen zur Kenntnis genommen. Es hat das Problem gelöst !!!
Also fand ich heraus, dass ich keinen behalten konnte, das ist genau die Ursache. Ich möchte nur meine Erfahrungen teilen, damit Sie eine weitere Rettung für Ihre App haben.
quelle
Öffnen Sie die Debugger-Konsole, indem Sie Cmd + Shift + R drücken. Geben Sie dort ein
break malloc_error_break
um einen Haltepunkt am Anfang der
malloc_error_break
Funktion zu setzen.Wenn Sie herausfinden möchten, welches Objekt sich unter der Adresse 0x1068310 befindet, können Sie Folgendes in die Debugger-Konsole eingeben:
print-object 0x1068310
Natürlich müssen Sie dies tun, während das Objekt noch lebt. Wenn das Objekt zu diesem Zeitpunkt bereits freigegeben wurde, funktioniert dies nicht.
quelle
po
Alias oder gleichwertigexpr -o
. In den Jahren, seit diese Antwort ursprünglich geschrieben wurde, wurde die von Xcode verwendete Debugging-Engine von GDB in LLDB geändert, und LLDB verfügt über einen anderen Befehlssatz.Für mich wurde das Problem durch gelöst
(gdb) call (void)_CFAutoreleasePoolPrintPools()
gleich nach dem Absturz. Die Adresse oben im Stapel war die Adresse des Täters.
retain
Warf ein und voila.Die in der Protokollnachricht angegebene Adresse brachte mich nicht weiter. Es tauchte in keinem der verschiedenen Instrumets auf. Anscheinend ein Zeiger auf einige interne Daten, die bereits freigegeben wurden.
quelle
Hinzufügen eines symbolischen Haltepunkts in Xcode 4
Nur ein Update, um dies für Xcode 4 relevant zu machen ...
Aus dem Xcode 4-Benutzerhandbuch :
quelle
So sieht der Haltepunkt malloc_error_break im Fenster Haltepunkte in Xcode aus. Sie müssen die Kontrollkästchen aktivieren, damit es funktioniert.
Alternativtext http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png
quelle
Überprüfen Sie Ihre Klassen und schauen Sie unter der Dealloc-Methode. Stellen Sie sicher, dass Sie anrufen möchten
[super dealloc].
Ich hatte genau das gleiche Problem und fand heraus, dass ich
[self dealloc]
stattdessen anrief . Nur nicht aufpassen.quelle
In den folgenden Schritten erfahren Sie, wie Sie das freie Objekt finden und die Anwendung zum Absturz bringen.
Sie können auch auf die folgende GIF-Präsentation verweisen.
quelle
Dies wird normalerweise von einigen Inspektoren verursacht, z. B. Safari oder Safari-Vorschau. Siehe Beitrag oder Beitrag und Frage .
Entfernen Sie die Auswahl von AutoMatisch Show Web ...., um dieses Problem zu beheben.
Beachten Sie, dass durch einfaches Schließen der Safari oder der Safari-Vorschau dieses Problem nicht behoben wird. Und Sie müssen sowohl die Safari- als auch die Safari-Vorschau deaktivieren.
Wenn dies nicht funktioniert, lesen Sie diese Antwort oder diesen Beitrag , um sie zu debuggen.
quelle
Klicken Sie in Xcode links neben der Zeilennummer, um einen Haltepunkt festzulegen. Dann können Sie es starten, indem Sie ein "Build and Debug" durchführen.
Es wird empfohlen, kein Objekt zu erstellen, das Sie erstellen,
autorelease
da Speicher auf dem iPhone eine Ware ist. Apple empfiehlt, ausdrücklich anzurufenrelease
.quelle
Um diese Art von Speicher- und Zeigerproblemen im Allgemeinen zu finden, möchten Sie Ihren Code gegen eine Laufzeit-Speicherfehlerprüfung wie Valgrind ausführen . Dies sollte in der Lage sein, auf viele Dinge hinzuweisen, die Ihr Code falsch macht, über die hinaus, die zum Absturz führen.
Valgrind kann unter OSX arbeiten (obwohl es heißt, es sei "nicht unterstützt und unvollständig und fehlerhaft"), und mit ein wenig Hacking hat es jemand dazu gebracht, an ausführbaren iPhone SDK-Dateien zu arbeiten .
Noch besser können Sie Instruments ausprobieren, das Teil von XCode ist. Es gibt ein Tutorial es für die Ausführung von hier .
quelle
Wenn
malloc_error_break
nicht hilft ...Der beste Weg, um diesen Fehler zu beheben, besteht darin, Instrumente mit
NSZombies
eingeschaltetem Gerät zu betreiben . Instrumente kennzeichnen Sie, wenn der Zombie eine Nachricht erhält, und Sie können direkt zur Codezeile zurückverfolgen.Schneeleopard erforderlich, was für ein Lebensretter!
quelle