gdb Debuggen "double free" - nicht erkannt werden von valgrind (?)
Etwa einmal alle drei Male, die ich aus meinem Programm, malloc Berichte zu einem double-free-Fehler; z.B.
myprogram(703,0xb06d9000) malloc: *** error for object 0x17dd0240: double free
*** set a breakpoint in malloc_error_break to debug
Habe ich den gleichen code über die valgrind-mehr als ein Dutzend mal, aber es nie Berichte zu einem double-free.
Mir lief der code durch den gdb mit einem Haltepunkt auf malloc_error_break und (wenn der bug Auftritt) der Fehler wird immer gemeldet, die in einem c++ - standard-library-Funktion. Ich isolierte die übergeordnete Funktion und valgrinded es in einer test-Einheit, aber keine Fehler.
Ich denke, die Eltern-Funktion/standard c++ library ist nicht Schuld, es ist einfach befreiend, etwas reserviert, aber eine andere Funktion, die in das übergeordnete Programm freigegeben.
Ich habe versucht zu suchen, welches Objekt doppelt freigegeben, aber mein gdb Fähigkeiten sind nicht bis zu der Feststellung, das erste Objekt, das befreit wurde. Bitte helfen Sie mir herauszufinden, welches Objekt verursacht wird die erste freie und zusätzlich jeder helfen, warum mein Programm erzeugt diesen Fehler. Danke.
Den übergeordneten Funktion darauf an:
int i;
double px, py;
int start, finish;
std::string comment;
std::vector<double> x, y;
std::fstream myfile;
myfile.open("filename.txt", std::ios_base::in);
//Read header
std::getline(myfile, comment);
//Read data
while(!myfile.eof())
{
myfile >> comment >> start >> comment >> finish;
for(i = 0; i <= finish-start; i++)
{
myfile >> px >> py; //double free here
x.push_back(px);
y.push_back(py);
}
}
BEARBEITEN:
Meine Daten-Datei ist so etwas wie dieses:
Comment: My Data
start 33 end 36
10.2 139.0076
9.22616 141.584
8.62802 141.083
8.87098 141.813
start 33 end 35
300.354 405
301.698 404.029
303.369 403.953
start 33 end 35
336.201 148.07
334.616 147.243
334.735 146.09
Der backtrace von gdb ist
(gdb) backtrace
#0 0x93c2d4a9 in malloc_error_break ()
#1 0x93c28497 in szone_error ()
#2 0x93b52503 in szone_free ()
#3 0x93b5236d in free ()
#4 0x93b51f24 in localeconv_l ()
#5 0x93c18163 in strtod_l$UNIX2003 ()
#6 0x93c192e0 in strtod$UNIX2003 ()
#7 0x919b76e8 in std::__convert_to_v<double> ()
#8 0x919983cf in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::do_get ()
#9 0x91991671 in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get ()
#10 0x9198d2dc in std::istream::operator>> ()
Nur zu wiederholen, ich brauche Hilfe, um herauszufinden, welches Objekt wurde freigegeben, das erste mal, ich bin nicht so interessiert dabei, meinen code für diese Funktion - was ich nicht glaube, dass das problem verursacht; es sei denn, Sie können etwas finden, katastrophal in es.
BEARBEITEN: Verändert den Beispiel-code.
- Kannst du (oder hochladen und einen link zu posten, wenn große) der Inhalt
filename.txt
verursachen, dass dieses Programm, um das Verhalten in Frage? Der code, den Sie geschrieben ist ziemlich nutzlos ohne Sie, da die Ablaufsteuerung des Programms hängt vom Inhalt der Datei. - Spaß, weil Sie sich nicht selbst befreien
- Genau, die Bibliothek-Funktion ist dabei die zweite frei, nicht mir.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie zu sein scheinen, mit Mac OSX (Sie sollte verraten, dass der Tat 🙂
Gibt es mehrere environment-Variablen, die helfen können Sie debug-heap-Beschädigung.
Insbesondere
MallocStackLoggingNoCompact
sieht sehr vielversprechend aus.Hier ist, was ich sehe:
Dieser erste Teil der Geschichte, die wir eigentlich gar nicht kümmern:
Aber hier ist die interessante Sache:
Ich bin derzeit versuchen, die Spur ein "Versuch, freien, nicht zugeordneten" pointer " - Fehler, auch auf MacOS. Mein Fehler wird ausgelöst, über den man in fünfzig läuft (identisch mit Eingang) des Programms, und, natürlich, es ist nie passiert, wenn ich habe seit es den debugger (seufz).
Was ich unten beschreiben ist ein bequemer Weg, um einen backtrace auf, die seltene Gelegenheit, bei der Fehler ausgelöst wird, ohne dass die Interaktion mit gdb auf jedem laufen. Es ist eine alternative zu EmployedRussian ' s gute Tipps.
Verwenden Sie die folgende gdb-Befehl Datei:
Gdb, die Ausführung der Befehlsdatei, wie diese:
Wenn das Programm läuft, ohne auf die Befreiung problem, es wird gedruckt "No stack" in Antwort auf den Befehl backtrace, dann gdb beenden (Dank --batch-option).
Wenn das Programm zuvor auf die Freigabe Fehler, werde ich (hoffentlich!) erhalten Sie einen Stapel, bevor gdb beendet.
hdestroy()
eine linux Funktion! :'(Diese Zeile:
nur Lesen " - Kommentar:" und nicht die gesamte Zeile "Bemerkung: Meine Daten". Das nächste, was, das Lesen von
myfile
nach dieser Zeile wird "meine", die wahrscheinlich Probleme verursachen.Insbesondere die erste Zeit durch die äußere Schleife, wird er versuchen zu Lesen, den string "Daten" in
start
, und nicht in der Lage, dies zu tun (denn es kann nicht analysiert werden, wie eine ganze Zahl ist). So die Aussage:wird abgebrochen, und beide
start
undfinish
verlassen wird, nicht initialisiert.Abhängigkeit von der (willkürlichen) initialisierten Werte von
start
undfinish
, könnte dies leicht Ihre innere Schleife unendlich. Einfügen einer unendlichen Anzahl von Elementen in einen Vektor wird wahrscheinlich führen zu seltsamen Verhalten, obwohl ich nicht sehen, den crash, dass Sie das tun... es läuft einfach für eine sehr lange Zeit und ich kill es, weil ich Geduld.Allerdings, wenn ich dieses Problem umgehen, durch das entfernen von "Meine Daten" von der ersten Zeile, ich kann laufen, Ihr Programm zu 10.000 mal ohne einen Absturz.
versuchen, gdb,
cont
zu der Absturz Stelle, dann geben Sie den backtrace (Typbt
); sehen, ob das hilft Sie aus, wo das problem ist (beachten Sie, müssen Sie kompilieren Sie Ihr Programm im debug-Modus g++ -g, drucken Sie eine lesbare backtrace).BEARBEITEN:
Auf den meisten Maschinen, wenn Sie freie/löschen Sie eine memory location der Zeiger, Sie sind zu befreien, nicht NULL-ed. An dem Punkt, wo du frei bist-ing der Speicher für die zweite Zeit, versuchen Sie, ein "= NULL", d.h.:
NICHT das problem zu beheben; jedoch, es wird zu isolieren, die Möglichkeit, dass die ersten free()/delete ist auch, dass genau die gleiche Linie (aber auf eine frühere Ausführung, sagen, wenn Sie auf einer Schleife).
btw, dein code-snippet enthält, die dynamisch allokierten Speicher (abgesehen von std::string, die intern Speicher dynamisch).
Haben Sie getroffen, einen Blick in das, was ist der Wert von start und Ziel und ob die Datei hat genug Inhalt zu füllen Vektoren x und y?
Ein besserer Ansatz wäre es, die re-Faktor der Schleife Logik -- Sie brechen sollten, der moment, in dem Sie hit-Datei EOF. An dieser Stelle haben Sie ließ es zu glauben.