2010-02-18 3 views
8

Ich habe in den letzten Wochen damit gearbeitet, einen wirklich schwierigen Bug zu finden, der meine Anwendung stürzt. Zuerst stürzte die Anwendung auf die Zuweisung einer std :: string, dann während der Freigabe einer lokalen Variablen ab.Ergänzung zu Valgrind?

Nach sorgfältiger Prüfung des Codes gab es keinen Grund für einen Absturz an diesen Stellen; es stürzte jedoch immer ab, während versucht wurde, einen ungültigen Zeiger freizugeben (d. h. einen Zeiger, der auf ungültigen Speicher zeigte). Und ich habe keine Ahnung, warum dieser Zeiger nicht auf den richtigen Ort zeigte.

Ich vermute, dass das Problem mit einem Speicherbeschädigungs-Problem oder Pointer-Korruptions-Problem irgendeiner Art zu tun hat. Das Problem ist, dass ich es nicht visuell aufspüren kann .... noch. Ich habe keine Ahnung, wo ich anfangen soll, im Code zu suchen, und es gibt Tausende von Codezeilen, die durchlaufen werden müssen, so dass dies nicht als realistische Annäherung an das Problem erscheint.

So kommt Valgrind ...

Ein Werkzeug, das ich über viele eine Zeit abhing haben Probleme im Code zu finden, die zu einem Absturz dieser Art führen kann. Dieses Mal ist es jedoch leer ausgegangen! Ich sehe keine Fehler in Valgrind, wenn das Problem auftritt und daher der Grund für mich, diese Frage zu stellen.

Gibt es noch andere Anwendungen, die Valgrind ergänzen und dabei helfen können, Probleme im Code zu finden, die den oben erwähnten Absturz verursachen könnten?

Vielen Dank!

+0

Sie könnten versuchen, ein minimales, übersetzbar Codebeispiel veröffentlichen, die das Problem reproduziert. Ich wette, dass der Versuch, ein solches Codebeispiel zu schreiben, das Problem für Sie offensichtlich macht. Wenn nicht, sind wir mehr als glücklich zu helfen. –

+0

Möchten Sie sehen, wo der Code abstürzt (d. H. Ein Beispiel, wo es abstürzt)? weil es keinen Grund dafür gibt, wie ich erwähnt habe, aber es macht mir nichts aus, es zu posten – bbazso

Antwort

0

Haben Sie versucht, mit Lint, Flexlint oder cppcheck. Dies kann helfen, ein Problem zu identifizieren.

Wenn Sie wissen, welcher Speicherbereich beschädigt ist, haben Sie versucht, diesen Speicher als geschützt zu markieren. Dies kann Ihr Problem maskieren und überhaupt nicht helfen, aber wenn der Punkt, an dem der Speicher geändert wird, immer noch abstürzt, hilft dies, Ihr Problem zu lösen.

+1

Wie können Sie die Erinnerung schützen? Ich habe das vorher noch nie gemacht ... – bbazso

5

Meiner Erfahrung nach haben Coverity und Purify solche Fehler verursacht, die Valgrind nicht hatte (alle fanden Probleme, die von den anderen nicht gesehen wurden).

Aber manchmal gibt kein Werkzeug einen Hinweis, und Sie müssen mehr graben, Instrumentierung hinzufügen, mit Breakpoints auf "Speicher bei Adresse ändern" spielen, versuchen Sie einfach den Testfall, der fehlschlägt und so weiter, um die Ursache herauszufinden. Das kann sehr schmerzhaft sein.

+0

Ich stimme dem Debugger-Kommentar zu. Manchmal ist es am besten, einen Unterbrechungspunkt im Speicher festzulegen, der weggeblasen wird und wartet. –

+0

Mit gdb, wie kann ich einen Haltepunkt im Speicher setzen, um zu sehen, wann es geschrieben ist? – bbazso

+0

der Befehl "Uhr", möglicherweise zusammen mit einer Bedingung auf, was Sie als ungültig betrachten –

1

Sie haben die Plattform nicht angegeben, aber ich kann Gimpel PC-lint als ein ausgezeichnetes statisches Analysewerkzeug empfehlen (lassen Sie sich nicht durch den Namen täuschen!). Sie bieten FlexeLint auch für andere Plattformen an, aber ich habe keine persönliche Erfahrung mit diesem Produkt.

+0

Gimpel Software ist ein tolles Outfit. 1 –

6

Ich nehme an, Sie verwenden Valmind memcheck Werkzeug, für das es berühmt ist. Da Sie Valgrind bereits verwenden, können Sie auch versuchen, Ihr Programm über valgrind --tool=exp-sgcheck (früher exp-ptrcheck) auszuführen, was ein experimentelles Tool ist, das bestimmte Arten von Fehlern abfangen kann, die mecheck verpassen wird, einschließlich Zugriffsprüfungen für Stack- und globale Arrays von Zeigern, die auf ein gültiges Objekt, aber nicht auf das beabsichtigte Objekt zeigen. Dies geschieht durch Verwendung eines völlig anderen Mechanismus, wobei im Prinzip jeder Zeiger in den Speicher verfolgt wird, anstatt den Speicher selbst zu verfolgen, und indem Heuristiken verwendet werden.

Beachten Sie, dass das Tool experimentell ist, aber Sie können feststellen, dass es etwas Bedeutendes fängt. Momentan unterstützt es OS X oder Nicht-Intel-Prozessoren noch nicht.

+0

Ich versuchte es, aber ich erhalte ein: sysno == 233 exp-ptrcheck: die 'unmöglich' geschah: unhandled syscall Irgendwelche Ideen? – bbazso

+0

Versucht es und dann ging es um 232 runter. :) Wo hast du die Zuordnung zwischen syscall no und was ist das? – bbazso

+0

'/ usr/include/asm-i386/unistd.h' (oder' asm-x86_64' für x86_64). Ich schätze mal, wieso ist es noch experimentell ... – mark4o

2

Ist es möglich, dass einige Stapelfehler auftreten? Ist dies der Fall, versuchen Sie, stack canaries mit der Option -fstack-protector-all zu aktivieren, vorausgesetzt, Sie verwenden g ++.

Hast du sonst Warnflags aktiviert, um verdächtigen Code zu identifizieren?

+0

habe ich die Fahne -stack-protector-all ausprobiert und auch libsafe probiert und beide kamen mit leeren Händen? :( – bbazso

0

Wenn Valgrind den ungültigen Zeiger identifizieren kann, der an free() übergeben wird, können Sie versuchen, das Programm unter DDD auszuführen, das eine Hardwareüberwachung auf dem Speicherort festlegen und das Programm anhalten kann, wenn es einen ungültigen Wert erhält. Wenn der Zeiger viel geändert wird, müssen Sie möglicherweise etwas Code um malloc schreiben und frei, um zu verfolgen, welche Werte gut und schlecht sind.

3

Meine Erfahrung ist, dass diese Art von Problem oft durch einen Heap-Überlauf verursacht wird. Electric Fence ist ein relativ einfaches Zuordnungs-Debugging-Tool, das ich gerne benutze. Es wird hauptsächlich als dynamisches Analysewerkzeug verwendet, um nach Heap-Überläufen zu suchen, eine Ergänzung zu "-fstack-protector-all", die nach Stack-Überläufen sucht.

More links zu efence Zeug.