16 Stimmen

Wie kann man mit Valgrind Details von Segmentierungsfehlern erkennen?

Ich habe eine std::map< std::string, std::string>, die mit einem API-Aufruf initialisiert wurde. Wenn ich versuche, diese Map zu verwenden, erhalte ich einen Segmentierungsfehler. Wie kann ich ungültigen Code erkennen, oder was ist ungültig oder irgendein Detail, das mir helfen kann, das Problem zu beheben? Der Code sieht wie folgt aus:

std::map< std::string, std::string> cont;

some_func( cont ); // getting parameter by reference and initialize it, someone corrupted memory (cont) inside this function

std::cout << cont[ "some_key" ] << '\n'; // segmentation fault here, cannot access "some_key"

4voto

kriss Punkte 22473

Starten Sie Ihre (im Debug-Modus kompilierte) Anwendung mit der Syntax:

valgrind yourapp

Valgrind zeigt Ihnen den Stack-Backtrace, wo der Segmentierungsfehler aufgetreten ist. Danach liegt es an Ihnen, herauszufinden, was passiert ist, und es zu korrigieren.

In Ihrem Code, unabhängig von valgrind, würde ich überprüfen, was zurückgibt cont[ "some_key" ] die wahrscheinlichste Ursache für Ihre Segfault ist, dass der zurückgegebene Wert einige wilde Zeiger oder überhaupt nicht initialisiert ist. Wenn dies der Fall ist, versuchen Sie, auf den Wert wie folgt zuzugreifen cont["some_key"][0] würde ebenfalls einen Segmentierungsfehler verursachen.

Eine andere Idee: Was ist mit den String-Schlüsseln in Ihrer Karte? Ist es möglich, dass einige von ihnen stillschweigend (ohne Ausnahme) den Datenteil des als Schlüssel verwendeten Strings nicht zuordnen konnten. Die std::map ist keine Hashtabelle, sondern nur ein geordneter Container. Bei der Suche nach einem Schlüssel kann es sein, dass sie auf andere Schlüssel zugreifen muss und da kann schon mal was passieren. Um das zu überprüfen, können Sie versuchen, auf alle Schlüssel in Ihrer Map zu iterieren und den Inhalt anzuzeigen (um zu sehen, ob das Problem speziell bei "some_key" auftritt oder ob Sie auf nichts in der Map zugreifen können.

Sie können es auch mit einer unordered_map versuchen, wenn Ihr Programm keine Ordnung braucht, um zu sehen, ob das Verhalten dasselbe ist.

3voto

Mark B Punkte 93261

Im Allgemeinen bin ich mir nicht sicher, wie diese Zeile einen Seg-Fehler erzeugen könnte: Der Klammeroperator gibt immer einen std::string zurück (und erzeugt bei Bedarf einen leeren), und dieser sollte immer für den Druck gültig sein.

Ist es möglich, dass der Aufrufstapel, den Sie sehen, stattdessen auf die nächste auszuführende Zeile verweist und diese in some_func stirbt? Wir sehen den Code dafür nicht, daher kann ich nicht sagen, ob das Problem dadurch verursacht werden könnte.

Abwechselnd ist some_func char* verwenden (ruft temp std::string auf), um Strings in der Map zu initialisieren? Es ist möglich, dass es eine ungültige Zeichenfolge in die Karte, die "zufällig zu arbeiten" für eine Weile, aber wenn some_func kehrt es nicht mit dem Druck gut interagieren könnte eingeführt werden.

0voto

Tom Punkte 41522

Zusätzlich zu valgrind könnten Sie versuchen, einen Debugger zu verwenden, um sich auf Ihr Problem zu konzentrieren.

Setzen Sie einen Haltepunkt in some_func(cont) Zeile, und prüfen Sie, ob cont ist eine gültige Referenz.

Haben Sie außerdem bedacht, was cont["some_key"] zurück, wenn some_key nicht vorhanden ist?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X