Ich habe einen seltsamen Fehler in meinem Programm, es scheint mir, dass malloc () einen SIGSEGV verursacht, was nach meinem Verständnis keinen Sinn ergibt. Ich verwende eine Bibliothek namens Simclist für dynamische Listen.
Hier ist eine Struktur, auf die später verwiesen wird:
%Vor%Und hier ist der Code:
%Vor% list_init
ist der Ort, an dem das Programm fehlschlägt, hier ist der Code für list_init:
Die Zeile l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS *
ist die Stelle, an der SIGSEGV entsprechend der Stack-Trace verursacht wird. Ich benutze gdb / nemiver zum Debuggen, bin aber ratlos. Wenn diese Funktion das erste Mal aufgerufen wird, funktioniert sie einwandfrei, aber beim zweiten Mal schlägt sie immer fehl. Wie kann malloc () eine SIGSEGV verursachen?
Dies ist der Stack-Trace:
%Vor%Jede Hilfe oder Einsicht wird sehr geschätzt!
Wahrscheinlich tritt in anderen Teilen Ihres Codes eine Speicherverletzung auf. Wenn Sie unter Linux sind, sollten Sie Valgrind auf jeden Fall ausprobieren. Ich würde meinen eigenen C-Programmen niemals trauen, wenn sie Valgrind nicht bestehen.
EDIT: Ein weiteres nützliches Werkzeug ist Elektrozaun . Glibc bietet außerdem die Umgebungsvariable MALLOC_CHECK_ , um Speicherprobleme zu beheben. Diese beiden Methoden beeinflussen die Laufgeschwindigkeit nicht so sehr wie Valgrind.
Wahrscheinlich haben Sie vor dem Aufruf durch einen Pufferüberlauf oder durch den Aufruf von free
mit einem Zeiger, der nicht von malloc
zugewiesen wurde (oder der bereits freigegeben wurde), einen Heapspeicher erstellt.
Wenn die von malloc verwendeten internen Datenstrukturen auf diese Weise beschädigt werden, verwendet malloc ungültige Daten und stürzt möglicherweise ab.
Es gibt unzählige Möglichkeiten, einen Core-Dump von malloc()
(und realloc()
und calloc()
) auszulösen. Dazu gehören:
malloc()
dort behalten hat). malloc()
dort behalten hat). malloc()
zugewiesen wurde. In einem gemischten C- und C ++ - Programm würde das das Freigeben von Speicher umfassen, der in C ++ von new
zugeordnet wurde. malloc()
zugewiesen wurde - was ein Spezialfall des vorherigen Falls ist. Die Verwendung einer Diagnoseversion von malloc()
oder das Aktivieren der Diagnose in der Standardversion Ihres Systems kann dabei helfen, einige dieser Probleme zu identifizieren. Beispielsweise kann es kleine Unterläufe und Überläufe erkennen (da es zusätzlichen Speicherplatz reserviert, um eine Pufferzone um den angeforderten Speicherplatz bereitzustellen), und es kann Versuche zum Freigeben von Arbeitsspeicher, der nicht zugewiesen wurde oder der bereits freigegeben wurde, erkennen oder Zeiger teilweise durch den zugewiesenen Speicherplatz - weil es die Informationen getrennt von dem zugewiesenen Speicherplatz speichert. Die Kosten liegen darin, dass die Debugging-Version mehr Speicherplatz benötigt. Ein wirklich guter Allokator ist in der Lage, die Stack-Trace- und Zeilennummern aufzuzeichnen, um Ihnen mitzuteilen, wo die Zuordnung in Ihrem Code stattgefunden hat oder wo der erste freie Code aufgetreten ist.
Sie sollten versuchen, diesen Code isoliert zu debuggen, um festzustellen, ob das Problem tatsächlich dort liegt, wo der Segfault generiert wird. (Ich vermute, dass es nicht ist).
Dies bedeutet:
# 1: Kompilieren Sie den Code mit -O0, um sicherzustellen, dass gdb korrekte Zeilennummerierungsinformationen erhält.
# 2: Schreiben Sie einen Komponententest, der diesen Teil des Codes aufruft.
Ich schätze, dass der Code bei separater Verwendung korrekt funktioniert. Sie können dann Ihre anderen Module auf die gleiche Weise testen, bis Sie herausfinden, was den Fehler verursacht.
Valgrind zu verwenden, wie andere vorgeschlagen haben, ist auch eine sehr gute Idee.