it-swarm.com.de

Wie kann man die Ursache für einen malloc "double free" Fehler finden?

Ich programmiere eine Anwendung in Objective-C und erhalte den folgenden Fehler:

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 freigebe und nicht herausfinden kann, welches Objekt ich zweimal freigebe.

Wie setze ich seinen Haltepunkt?

Gibt es eine Möglichkeit zu wissen, was das "Objekt 0x1068310" ist?

80
gonso

Sie werden herausfinden, was das Objekt ist, wenn Sie den Debugger unterbrechen. Schauen Sie einfach in den Call-Stack und Sie werden feststellen, wo Sie ihn freigeben. Das wird Ihnen sagen, welches Objekt es ist.

Der einfachste Weg, den Haltepunkt zu setzen, ist:

  1. Gehen Sie zu Ausführen -> Anzeigen -> Haltepunkte (ALT-Command-B)
  2. Scrollen Sie zum Ende der Liste und fügen Sie das Symbol malloc_error_break
37
Frank Krueger

Wenn ein Objekt "doppelt freigegeben" ist, liegt die häufigste Ursache darin, dass Sie ein automatisch freigegebenes Objekt (unnötigerweise) freigeben, und es wird später automatisch freigegeben, wenn der enthaltene Pool für die automatische Freigabe geleert wird.

Ich habe festgestellt, dass der beste Weg, die zusätzliche Version zu finden, darin besteht, die Umgebungsvariable NSZombieEnabled für die betroffene ausführbare Datei in Xcode zu verwenden. Eine kurze Beschreibung der Verwendung finden Sie unter diese CocoaDev-Wiki-Seite . (Zusätzlich zu dieser Seite hat Apple) einige unglaublich undurchsichtige und dennoch nützliche Tipps zum Debuggen von Code in Xcode dokumentiert, von denen einige meinen Speck mehr als ein paar Mal gespeichert haben. Ich empfehle, dass Sie sich Folgendes ansehen: dieser technische Hinweis auf developer.Apple.com - Der Link springt zum Abschnitt über das Cocoa Foundation Framework.

Bearbeiten: Sie können das fehlerhafte Objekt im Xcode-Debugger oft 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 starten → 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 Instruments ein Zombies-Tool hinzu, das Sie über das Menü Ausführen aufrufen können auch. Könnte allein die 29 Dollar wert sein! ;-)

Es gibt auch eine verwandte SO Frage hier .

45
Quinn Taylor

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, um diese Objekte später in den Ansichten anzuzeigen. Tatsächlich funktioniert die App einwandfrei und stürzt überhaupt nicht ab, bis ich einen Stresstest zum mehrmaligen Hin- und Her-Navigieren durchgeführt und versucht habe, 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 hatte, und konnte immer noch nicht herausfinden, wo genau die Ursache lag.

Ich habe NSZombieEnabled = YES und NSStackLogging = YES gesetzt und den Befehl Shell 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, in der Tat habe ich tausendmal die überfreigegebenen Objekte dort überprüft, nichts Ungewöhnliches.

Das Ausführen von Instrumenten mit verschiedenen Werkzeugen (Zuordnungen, Lecks usw.) hat immer noch nicht geholfen. Aktivieren Sie die Wache Malloc hat immer noch nichts.

Letzte Rettung: Ich habe versucht, zu den Ansichten zurückzukehren, in denen die Objekte aus den Stammdaten 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 eines nicht behalten konnte, das ist genau die Ursache. Ich möchte nur meine Erfahrungen teilen, damit Sie eine weitere Rettung für Ihre App haben.

12
Hoang Pham

Öffnen Sie die Debugger-Konsole, indem Sie Cmd + Shift + R drücken. Dort geben Sie

break malloc_error_break

um einen Haltepunkt am Anfang der Funktion malloc_error_break 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 dem Zeitpunkt, zu dem Sie dies tun, bereits freigegeben wurde, funktioniert dies nicht.

9
Adam Rosenfield

Für mich wurde das Problem durch gelöst

(gdb) call (void)_CFAutoreleasePoolPrintPools()

gleich nach dem Absturz. Die Adresse oben auf dem Stapel war die Adresse des Täters. Warf ein retain und voila.

Die in der Protokollmeldung angegebene Adresse hat mich nicht weiter gebracht. Es ist in keinem der verschiedenen Instrumets aufgetaucht. Anscheinend ein Hinweis auf einige interne Daten, die bereits freigegeben wurden.

4
c-alpha

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 :

Hinzufügen eines symbolischen Haltepunkts. . .

  1. Klicken Sie in der linken unteren Ecke des Haltepunktnavigators auf die Schaltfläche Hinzufügen.
  2. Wählen Sie Symbolischen Haltepunkt hinzufügen.
  3. Geben Sie den Symbolnamen in das Feld Symbol ein.
  4. Klicken Sie auf Fertig.
4
Old McStopher

So sieht der Haltepunkt malloc_error_break im Fenster Haltepunkte in Xcode aus. Aktivieren Sie die Kontrollkästchen, damit es funktioniert.

Alternativtext http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png

3
Martijn Thé

Überprüfen Sie Ihre Klassen und suchen Sie unter der Dealloc-Methode. Stellen Sie sicher, dass Sie [super dealloc]. Anrufen.

Ich hatte genau das gleiche Problem und fand heraus, dass ich stattdessen [self dealloc] Anrief. Nur nicht aufgepasst.

2
Wes Duff

Gehen Sie wie folgt vor, um das freie Objekt zu finden und die Anwendung zum Absturz zu bringen.

1) Klicken Sie auf " Breakpoint Navigator".
2) Klicken Sie anschließend auf die Schaltfläche " +".
3) Fügen Sie den " Symbolic Breakpoint ..." aus der Liste hinzu.
4) Fügen Sie das Schlüsselwort " malloc_error_break" in die Option " Symbol" ein.

Oder Sie können auch auf die unten stehende GIF-Präsentation verweisen.

GIF represenation

2

Dies wird normalerweise von einigen Inspektoren verursacht, z. B. Safari oder Safari-Vorschau. Siehe Beitrag oder Beitrag und Frage .

Entfernen Sie die Auswahl von AutoMatically Show Web ...., um dieses Problem zu beheben.

Hinweis: Durch Schließen der Safari oder der Safari-Vorschau wird dieses Problem nicht behoben. Und Sie müssen sowohl Safari als auch Safari-Vorschau deaktivieren.

Wenn dies nicht der Fall ist, beziehen Sie sich auf diese Antwort oder Post) um es zu debuggen.

deselect automatically inspect on safari preview

1
Kris Roofe

Klicken Sie in Xcode links von der Zeilennummer, um einen Haltepunkt festzulegen. Dann können Sie es starten, indem Sie "Build and Debug" ausführen.

Es wird empfohlen, kein Objekt zu erstellen, das autorelease ist, da der Speicher eine Ware auf dem iPhone ist. Apple empfiehlt den expliziten Aufruf von release.

0
Benny Wong

Um diese Art von Speicher- und Zeigerproblemen im Allgemeinen zu finden, möchten Sie Ihren Code mit einem Laufzeitspeicherfehlerprüfprogramm wie Valgrind ausführen. Dies sollte in der Lage sein, auf viele Dinge hinzuweisen, die Ihr Code falsch macht, abgesehen von denen, die zum Absturz führen.

Valgrind kann unter OSX funktionieren (obwohl es heißt, dass es "nicht unterstützt und unvollständig und fehlerhaft" ist) und mit ein wenig Hacking hat es jemand zum Arbeiten gebracht ausführbare iPhone SDK-Dateien .

Noch besser ist es, Instrumente auszuprobieren, die Teil von XCode sind. Es gibt ein Tutorial, um es auszuführen hier .

0
Jared Oberhaus

Ob malloc_error_break hilft nicht ...

Die beste Möglichkeit, diesen Fehler zu beheben, besteht darin, instruments mit eingeschaltetem NSZombies auszuführen. Instrumente markieren Sie, wenn der Zombie benachrichtigt wird, und Sie können direkt zur Codezeile zurückverfolgen.

Schneeleopard erforderlich, was für ein Lebensretter!

0
iOSDevSF