Debugging / Fehlerangabe in STL Header
-
Hallo Leute,
ich habe irgendwo in meinem Code eine Access Violation.
Der Code ist zu groß um diesen hier zu posten. Wenn ich debugge, wird der Fehler in der "stl_unintialized.h" angegeben - hier der entsprechende Code:#ifndef _STL_UNINITIALIZED_H #define _STL_UNINITIALIZED_H 1 _GLIBCXX_BEGIN_NAMESPACE(std) template<bool> struct __uninitialized_copy { template<typename _InputIterator, typename _ForwardIterator> static _ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { _ForwardIterator __cur = __result; __try { for (; __first != __last; ++__first, ++__cur) ::new(static_cast<void*>(&*__cur)) typename //HIER iterator_traits<_ForwardIterator>::value_type(*__first); return __cur; } __catch(...) { std::_Destroy(__result, __cur); __throw_exception_again; } } };In std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () ()
At c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_uninitialized.h:74Ich habe meinen Quelltext nach möglichen Fehlerquellen wie z.B vergessene Nullterminierung/Pufferüberläufe,.. durchsucht, aber nichts gefunden.
Worauf lässt sich eine solche "Fehlerbeschreibung" desweiteren hinweisen?
Oder gibt es sonst Möglichkeiten, wie ich den Fehler finden könnte, wo sich dieser versteckt?
Habe leider keine wirkliche Ahnung davon.
Danke im voraus
-
Wenn dein Debugger nen call stack anzeigt, kannst du einfach nachgucken, an welcher Stelle in deinem Programm das Problem auftritt. Vom Namen der .h tipp ich mal darauf, dass du irgendwo aus einer nicht-initialisierten Variable liest. Die Debug-Version deiner STL fängt das ab. Im Release würdest du vermutlich nix merken.
Aber such jetzt besser nicht dein ganzes Programm nach solchen Fällen ab, sondern schau dir an, wie dich dein Debugger direkt dahinbringen kann. Da hast du für die Zukunft mehr von.
-
Der Fehler liegt mit 99.999999% nicht in der STL, sondern da drin, wie du sie benutzt. in einem optimierten Programm hat die STL normalerweise keinerlei Sicherheitsabfragen, d.h. wenn du etwas falsch machst, dann kracht es eben dort. Schuld ist aber dein Programm. Gehe mal im Stackframe nach oben, bis zu deinem Programm. Dann weißt du, wo der Fehler fliegt und kannst dir dann erschließen, warum. Oder falls du es dir nicht erschließen kannst, dann setz mal so etwas wie valgrind auf dein Programm an (leider nur unter Linux-artigen Systemen, k.A. ob es ähnliches für Windows gibt), damit findet man erfahrungsgemäß recht flott die Ursache solcher Probleme.
Oder benutz eine Debugversion der STL.
P.S.: Bei der Fehlermeldung hast du übrigens den interessanten Teil weggelassen. Nämlich den Fehler.
-
Danke erstmal. Ja, ich habe vergessen zu sagen dass ich Windows Vista nutze. Dass der Fehler nicht in der STL liegt habe ich mir auch zu 99,999999% gedacht. Ich nutze auch den Call Stack. Ich habe mal ein Foto hochgeladen. Das Problem ist nur, ich hab nichts am Code geändert. Und der Code der hinzugefügt/geändert wurde, ist auskommentiert.
http://s14.directupload.net/images/111229/4uz5htio.jpgVorher waren nicht all diese Fehler vorhanden.
Auch im Release funktioniert es nicht.
Nur gibt es sonst eine Möglichkeit, herauszufinden, wo die Initialisierung fehlerhaft ist? Kann es sein, dass es sich um den Vektor geht, welcher so aufgebaut ist:
std::vector<std::vector<std::string> > vect(2, std::vector<std::string>());Normalerweise erhalte ich die Daten über einen blocking Socket und wird dann initialisiert. Auch ohne Daten zu erhalten, läuft das Programm weiter - wie ich gerade bemerkt habe...
hm, aber eine direkte Fehlermeldung erhalte ich nicht.Program received signal SIGSEGV, Segmentation fault.
In std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () ()
At c:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_uninitialized.h:74
-
Wo bringt deine IDE dich denn hin wenn du auf Nr. 7 in deinem Callstack klickst? Irgendwas passiert in Zeile 114 in der Datei, in der getvaluesfromrecv::getvaluesfromrecvfunction definiert ist. Da schiebst du irgendwas in einen vector.
-
zuckerlie schrieb:
Ich nutze auch den Call Stack.
Gut. Im Call-Stack-Window klickst Du natürlich auf Deinen Nutzcode, die getvaluesfromrecv wohl, und machst noch ein Watch-Fenster für lokale Variablen auf und inspizierst die. Und immer auch mal this anschauen. Manchmal ist this==0 und dann geht alles schief, obwohl alles richtig aussieht.
-
Ach verdammte Scheisse

Man sollte seinen Vector für jeden neuen Aufruf wieder leeren.

Also es liegt scheinbar daran. Aber wieder was gelernt :).
Aber nebenbei, debuggen waren bei 30,40 Zeilen Code nie ein Problem. Allerdings fängt es jetzt eins zu werden, wenn man insgesamt auf paar hundert Zeilen Code

Gibt es wohlmöglich Tutorials, wie man richtig "debuggt"?
Danke Leute
Ihr habt mir mein Leben gerettet
-
zuckerlie schrieb:
Danke Leute
Ihr habt mir mein Leben gerettetScheint sich um wichtigen Code zu handeln, wie?

zuckerlie schrieb:
Gibt es wohlmöglich Tutorials, wie man richtig "debuggt"?
Wüsste ich keins, aber gibts wahrscheinlich schon. Am besten kombinierst du die Features des Debuggers, damit hast du mächtige Werkzeuge zur Hand (Haltepunkte, Variablen- und Ausdrucküberwachung, Callstack, schrittweises Durchgehen).
Wichtiger finde ich allerdings Techniken, mit denen man Debug-Sessions enorm verkürzen kann:
- Vermeide Low-Level-Sprachmittel wie manuelle Speicherverwaltung, mehrfache Zeigerindirektionen, Arrays, C-Strings und ersetze sie durch gekapselte Äquivalente (Container, Smart-Pointer, spezialisierte Klassen). Das macht deinen Code nicht nur sicherer, sondern auch einfacher und übersichtlicher.
- Halte Abhängigkeiten zwischen einzelnen Modulen klein und verzichte weitgehend auf globale Variablen, Singletons o.Ä. Dadurch bleiben auch Fehler lokal, haben weniger Seiteneffekte und können somit schneller gefunden werden.
- Benutze Assertions und Klassen, die sie ebenfalls einsetzen (jede vernünftige STL-Implementierung sollte diverse Checks im Debug-Modus durchführen können).
- Achte darauf, Logikfehler nicht zu vernebeln. Wenn eine Funktion ungültige Parameter bekommt, lass sie nicht einfach weiterlaufen oder normal beenden, sondern reagiere sofort darauf (bei Logikfehlern mit
assert). Damit verhinderst du, dass sich der Fehler weiterzieht und dann an einem Ort Probleme verursacht, wo er schwer nachvollziehbar ist. - Passe auf heimtückische Gefahrenquellen auf: Ungültige Iteratoren, Zeiger und Referenzen; Reihenfolge der Konstruktor-Initialisierungsliste; Aufrufe virtueller Methoden im Konstruktor und Destruktor; Slicing; etc.
- Bastle bestehende Implementierungen nicht unnötigerweise nach. Die Standardbibliothek und Boost bieten für sehr viele Probleme Lösungsansätze. Nutze diese, denn die Wahrscheinlichkeit ist hoch, dass sie getestet und optimiert sind.
- Setze auf bekannte Idiome wie RAII oder Copy-and-Swap. Als Folge davon bekommst du Exceptionsicherheit und automatische Speicherverwaltung oft gratis.
-
zuckerlie schrieb:
Gibt es wohlmöglich Tutorials, wie man richtig "debuggt"?
Nicht dass ichs wüsste - Erfahrung ist da nicht zu ersetzen.
-
Vielen Dank!
Scheint sich um wichtigen Code zu handeln, wie?

Ja

Ja, in die Features arbeite ich mich ein. Aber das bedarf auch Zeit
Vielen Dank für die Punkte!Nicht dass ichs wüsste - Erfahrung ist da nicht zu ersetzen.
Natürlich, nichts ist besser, als Erfahrung

-
zuckerlie schrieb:
Gibt es wohlmöglich Tutorials, wie man richtig "debuggt"?
Also mir hat in meiner Anfangszeit dies sehr geholfen:
Peter's gdb Tutorial
Das ist natürlich, wie der Name schon sagt, für den GNU Debugger, nicht für den Visual Studio Debugger. Es enthält aber auch viele allgemeine Vorgehensweisen und Techniken, insbesondere der Abschnitt "Debugging with your Brain". Dieser setzt aber voraus, dass du Brain.exe installiert hast
.
-
-
Danke

Ja, ich nutze den GNU Debugger
Visual Studio ist nicht so mein Ding 
Brain.exe - Einfach nur TOP die Seite

Ich werde mir das Buch mal anschauen.