2013-08-03 17 views
8

bearbeiten Voll Quelle ist hier:malloc() stürzt ab, sagen beschädigte doppelt verkettete Liste

http://code.seanwoods.com/reynard.fossil.cgi/artifact/0cc9cbfbe021c2ba86dcb4d0cf6ada52f0a80063

Aufruf Programm hier:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/891405e62c95349aaf461dfb8ba82259f77fac9b

ich ein relativ habe einfache Speicherzuweisung, die fehlschlägt. Die Anwendung ist nicht besonders kompliziert, obwohl sie Speicherplatz an einigen Stellen reserviert. Es ist C, nicht C++. Ich bin sicher, das ist ein Problem Zuweisung Speicher, nicht Freigabe Speicher.

Hier ist der Code:

printf(":2 %d %d\n", initial_len, initial_len * sizeof(char)); 
o->data = (char*) malloc(initial_len * sizeof(char)); 
printf(":3 \n"); 

Bei der Ausführung, die ich erhalten:

:1 
:2 1024 1024 
*** glibc detected *** ./menv: corrupted double-linked list: 0x0000000001d14400 *** 
======= Backtrace: ========= 
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f680cfc4d76] 
/lib/x86_64-linux-gnu/libc.so.6(+0x771ed)[0x7f680cfc51ed] 
/lib/x86_64-linux-gnu/libc.so.6(+0x794d4)[0x7f680cfc74d4] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7f680cfc9b90] 
./menv[0x403971] 
./menv[0x40391d] 
./menv[0x4030ec] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f680cf6cead] 
./menv[0x401369] 
======= Memory map: ======== 
00400000-00405000 r-xp 00000000 08:03 2621441       /home/swoods/code/reynard/modules/stdlib/menv 
00605000-00606000 rw-p 00005000 08:03 2621441       /home/swoods/code/reynard/modules/stdlib/menv 
00606000-00706000 rw-p 00000000 00:00 0 
01cfd000-01d3d000 rw-p 00000000 00:00 0         [heap] 
7f6808000000-7f6808021000 rw-p 00000000 00:00 0 
7f6808021000-7f680c000000 ---p 00000000 00:00 0 
7f680cd38000-7f680cd4d000 r-xp 00000000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cd4d000-7f680cf4d000 ---p 00015000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cf4d000-7f680cf4e000 rw-p 00015000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cf4e000-7f680d0ce000 r-xp 00000000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d0ce000-7f680d2ce000 ---p 00180000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2ce000-7f680d2d2000 r--p 00180000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2d2000-7f680d2d3000 rw-p 00184000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2d3000-7f680d2d8000 rw-p 00000000 00:00 0 
7f680d2d8000-7f680d2da000 r-xp 00000000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d2da000-7f680d4da000 ---p 00002000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4da000-7f680d4db000 r--p 00002000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4db000-7f680d4dc000 rw-p 00003000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4dc000-7f680d4fc000 r-xp 00000000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6df000-7f680d6e2000 rw-p 00000000 00:00 0 
7f680d6f8000-7f680d6fb000 rw-p 00000000 00:00 0 
7f680d6fb000-7f680d6fc000 r--p 0001f000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6fc000-7f680d6fd000 rw-p 00020000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6fd000-7f680d6fe000 rw-p 00000000 00:00 0 
7ffff3bd6000-7ffff3bf7000 rw-p 00000000 00:00 0       [stack] 
7ffff3bff000-7ffff3c00000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
Aborted 
  • Der Code ohne Probleme kompiliert.
  • Wenn ich es "Standalone" ausführen, stürzt es mit dem obigen Fehler ab. Ich sehe :2, aber ich sehe nicht :3, die mir sagt, es ist ein Fehler innerhalb malloc. (Ich hoffe, ich liege falsch.)
  • Wenn ich die gleiche Binärdatei über valgrind ausführen, funktioniert es wie erwartet.
  • Es scheint kein Problem mit der Variablendeklaration o->data, die eine char* ist. Wenn ich char* A; A = anstelle von o->data = deklariere, stürzt es immer noch ab.

Ich würde sehr gerne irgendwelche Ideen, wie zur Fehlerbehebung/warum das passiert.

Danke!

+1

Ist '* o' Objekt zugewiesen? – ouah

+4

Sie müssen eine SSCCE bereitstellen: http://sscce.org/ –

+1

Sie müssen ein vollständiges, kompilierbares Beispiel sehen, wie andere gesagt haben, aber werfen Sie in der Zwischenzeit keine Rückgabe von 'malloc()', und benutze 'sizeof (char)' nicht, da es immer '1' ist. –

Antwort

-1

EDIT: Da wir fast keine Ahnung haben, wie Ihre Struktur aussieht und welcher Datentyp o->data sein sollte, können wir nur spekulieren, was Sie zu tun versuchen.

Bitte geben Sie die o Strukturdefinition an, damit wir Ihnen helfen können.

+1

Fast sicher falsch.Wenn Sie 'char'-Zeiger zuweisen würden, würden Sie das Ergebnis in einem' char ** 'speichern, nicht in einem' char * ', obwohl es zugegebenermaßen, ohne ein vollständiges Beispiel zu sehen, unmöglich ist, den Typ' o-> data' zu bestimmen ist, aber sein Code ist zumindest konsistent und dein ist es nicht. –

+0

Ich muss sagen, ich habe anscheinend schlampig beim Lesen. Mein Fehler. Der Typ der Eigenschaft 'o-> data' sollte angegeben werden, um zu empfehlen, was er zu tun versucht. Meine Vermutung war, dass er versucht, eine Zeichenfolge zu speichern. Aber wenn er seinen Code erneut anschaut, würde er vorschlagen, dass er versucht, etwas anderes zu tun ... Ich werde meinen Beitrag bearbeiten. – DaMachk

+2

Die aktualisierte Antwort wäre besser als Kommentar. Sie sollten in der Lage sein, Ihre eigenen Antworten zu löschen, wenn Sie die downvotes hier entfernen möchten – simonc

13

Also, ich denke, ich habe es gefunden. Möglicherweise müssen wir dies unter "Sean muss grundlegende Valgrind Fähigkeiten zu lernen." So habe ich es für zukünftige Beobachter gelöst.

  1. Okay, es zu tun wir mit einem wirklich seltsamen Fehler ausgelöst durch eine erprobte und Bibliothek Funktion getestet, also muss es etwas Bestimmtes zu meinem Setup sein. Der Algorithmus ist derselbe, , also muss es die Daten sein.
  2. Die dynamische Speicherimplementierung hat eine zugrunde liegende Datenstruktur zum Verfolgen zugeordneter Speicher, die zufällig eine doppelt verkettete Liste ist - also die Nachricht.
  3. Also, es muss eine Speicheroperation irgendwo sein, dass diese Datenstruktur in eine subtile Art und Weise korrumpiert.
  4. Okay, welche Werkzeuge haben wir zur Verfügung? Valgrind wird sehr gelobt, versuchen wir das. Seltsam, es funktioniert in Valgrind. Hmm.
  5. Lesen Sie tatsächlich, was Valgrind Ihnen sagt. (Dies ist, wo ich meinen Teil nicht getan habe.) Es kennzeichnet Sie mit Fehlern wie "Ungültige Schreiben der Größe 1" zusammen mit einer Spur der verschiedenen Labels/Symbole, wo dies auftaucht. Suchen Sie nach möglichen Fehlern und passen Sie sie als an.
  6. In diesem Fall zeigte es mich auf einen Aufruf von memcpy() in der Funktion hashtable.chashtable_put. Der subtile Hinweis ist, dass ich das erste Argument an memcpy mit dem Address-Of-Operator & übergeben habe, der die Korruption verursacht hat.
  7. Als ich das reparierte, beschwerte sich Valgrind nicht mehr.

Die Moral der Geschichte:

  • Feedback von den Tools nicht ignorieren Sie. Keine Nachrichten sind [normalerweise] gute Nachrichten, also wenn Valgrind viele Informationen ausspuckt, ist eine erhöhte Wahrscheinlichkeit eines Problems.
  • Dynamische Speicherzuweisung Fehler sind subtil (dynamische im wahrsten Sinne des Wortes) und kann von vielen Variablen betroffen sein. Valgrind stellt die Dinge in die Mitte Ihres Programms und der Speicherbibliothek, so dass es weiß, was vor sich geht, also denke ich, dass diese den Betrieb des Programms irgendwie beeinflusst haben .

Der dass commit hat festgelegt, so weit das Problem:

http://code.seanwoods.com/reynard.fossil.cgi/ci/bd6a5a23c1?sbs=0

+0

Guter Job, der Ihr eigenes Problem repariert. Ich habe auch Ihren Code erfolgreich kompiliert und ausgeführt (mit ein paar Korrekturen, um Warnungen loszuwerden), wobei die Kommentare um Ihre 'main()' Funktion entfernt wurden, so dass dies ein weiterer Hinweis darauf gewesen wäre, dass das Problem anderswo war. –

+0

Hallo, ich bin auch auf das Problem gestoßen, auf das Sie in meinem eigenen Code hingewiesen haben. Ich konnte Ihre Lösung jedoch nicht verstehen ... Ich ging durch den Code und der folgende Punkt ist unklar: Was ist der Zusammenhang zwischen dem Aufruf von memcopy() und malloc()? Ich sehe absolut keine Beziehung. Ich verpasse sicherlich etwas sehr subtiles. –

Verwandte Themen