Wie debuggt man SIGSEGV´s?
-
Hallo, ich code erst ein paar Wochen C++, ich nutze hierbei code::blocks als editor mit den eingebauten GNU gdb 6.8 als debugger.
Ich komme hierbei des öfteren mal dazu das ein SIGSEGV gemeldet wird und ausser der Zeile in der der Fehler auftritt habe ich so gesehen keine weiteren Angaben zum Fehler.
Daher nun meine Frage ob es da ein Debugging Tutorial oder dergleichen gibt, denn ohne weitere Beschreibung fehlen mir einfach Anhaltspunkte.
Von daher wären Links zum Debuggen von SIGSEGV´s unter verwendung von code::blocks mit eingebauten debugger sehr nett.
Aktuelles Beispiel wäre eine selbsterstelle Klasse in der ich eine andere Klasse erweitere und dann versuche 2 mal eine Collisiondetection zu machen, die erste Brauche ich um auszuschliessen das der Laserstrahl einer Waffe auf die Playerklasse (meine Klasse in einem 3D Game) trifft die zweite Collisiondetection wird benötigt um herauszufinden wo die Kollision beim Target (genauer Punkt) stattfindet um dort einen Effekt abzuspielen.
Die erste Collisiondetection klappt bei der zweiten (habe hier unterschiedliche Variablen und Instanzen vordefiniert und die Synthax gleichbelassen) bekomme ich oben besagten SIGSEGV mit hinweis auf die zweite Collisiondetection ohne weider Angabe woran es liegt.mfg
-
Was steht denn an der Stelle, wo der Segmentation Fault auftritt? Wenn eine Funktion aufgerufen wird, setze den Breakpoint halt in der anderen Funktion...
-
dann geht zumindest bei code::blocks ein debug fenster mit der reihenfolge der aufgerufenen funktione klassen, der speicher addresse und der dazugehörigen datei und zeile auf. der breakpoint ist gelb und weitere informationen erhalte ich nicht, das ist ja mein problem...
bei dem beispiel oben war es das ein result eine funktionsabrfrage (targetObjekt->getSelector()) nicht in einer Klassenvariablen gespeichert wurde, ich hab die selbe abfrage dann in die gleiche (myClass::render) funktion übernommen und schon gings.
aktuell habe ich beispielsweise ein anderes problem.. ich erstelle in der selben Klasse ein objekt welchem ich keinnen Parent zuteile, beim schliessend es debug fensters tritt jedes 3-4te mal nun ein SIGSEGV auf, vergebe ich einen parent ausserhalb der klasse tritt der SIGSEGV immer auf nehme ich die selbe klasse (was aber auch bedeuted das ich position und rotationswerte mit übernehme was hier nicht erwünscht ist) tritt der SIGSEGV nicht auf.
wäre halt schön zu wissen wenn du oder sonstwer mir sagenkönnte wie ich eine detailierte ausgabe erhalte von dem was da schief gelaufen ist.
mfg
-
WeakPeak schrieb:
dann geht zumindest bei code::blocks ein debug fenster mit der reihenfolge der aufgerufenen funktione klassen, der speicher addresse und der dazugehörigen datei und zeile auf. der breakpoint ist gelb und weitere informationen erhalte ich nicht, das ist ja mein problem...
Habe ich das richtig verstanden, dein Programm stürzt ab, bevor der Debugger den Breakpoint erreicht? Dann setz den Breakpoint weiter vorne.
Wenn du die Zeile genau weißt, wo der Fehler auftritt, dann schau nach, in welcher Funktion der Fehler auftritt und debugge dort nochmal.
Nimmst du auch immer schön F7 zum Schritte machen?
-
Ich war wohl unwissend (was nicht heisst das ich nun wissender bin) aber ich arbeite mich gerade in die benutzung und handhabung des debuggers rein...
der breakpoint des debuggers befindet sich hier:
bool drop() const { // someone is doing bad reference counting. _IRR_DEBUG_BREAK_IF(ReferenceCounter <= 0) --ReferenceCounter; if (!ReferenceCounter) { delete this; return true; } return false; }
und wird erreicht ,der code gehört übrigens zu der rendering engine die ich benutze (Irrlicht heisst sie falls das jemandem etwas sagt).
Dieser SISEGV tritt nur auf wenn ich in einer selbstgeschribenen Klasse, eine Standartklasse benutze (ISceneNode) in der ich den Parent ausserhalb dieser selbstgeschribenen Klasse lege.
Dabei wird wohl beim Compilieren eine Refferenz wohl nicht gezählt so das beim beendigen des Programms der besagte SIGSEGV auftritt welcher von dieser Zeile in meiner main welche die Irrlicht.dll includet ausgeht:
device->drop();
Wie gesagt versuche ich mich gerade mit dem Debugger zurecht zu finden und bin dabei auf das gestossen:
http://www.bilder-hochladen.net/files/big/43qm-5f.png
ging leider nur als Bild
Da ich noch nicht wirklich lange c++ Programmiere habe ich halt so einige Probleme und weiss nicht wo dann da der Fehler liegt wenn soetwas auftritt.
kann mir dazu einer weiterhelfen?
-
Da ich Irrlicht schon mal gehört habe, gehe ich davon aus, dass das nicht deine eigene Bibliothek ist?! Dann kannst du wohl auch schlecht den Source der DLL debuggen. Ansonsten kenne ich mich damit nicht aus, tut mir leid
.
-
Machst du vllt. neben dem drop() auch ein delete device?
Zu dem drop() muss es eigentlich noch ein Pendant zum Hochzählen des Reference Counters geben. Wenn du das vergisst, das Objekt in der Zwischenzeit gelöscht wird (da keine Referenzen mehr gezählt werden sind), und du dann drop() auf dem nicht mehr existenten Objekt aufrufst, gibt es natürlich ein SEGFAULT.
Ein etwas größerer Kontext wäre auch nicht schlecht, dass man sieht
was du im Konstruktor deiner Klasse machst
im Destruktor
wie du Objekte deiner Klasse instantiierst, speziell wie deine node den anderen parent bekommt.
-
Bin das Problem los geworden, so wie es ausschaut liegt es wohl an der Reihenfolge wie der Compiler die einzelnen Objekte ordert. Zudem gab es mal einen bug in der kombi GCC/GDB der etwas mit vtables zu tun hatte... aber ich tippe mit meiner laienhaften Meinung mal auf das erstere.
@wxSkip korrekt, ist nicht meine lib/engine, allerdings ist die Rendering Engine Irrlicht open source, wäre also schon möglich die DLL vom Source zu erstellen und diesen zuvor zu ändern, wäre mir aber lieb wenn ich erstmal etwas mehr von C++ verstehe bevor ich in Bibliotheken rumfuchtel was im endeffekt dann darauf hinauslaufen würde das mir dann wohl kaum noch einer helfen könnte, bin halt ein C++ noob.. aber ich arbeite hart dran..
@l'abra d'or
Die Methode zum hochzählen ist ein "grab()" auch in der selben header Datei, die wird beim erstellen aller Nodes aus der dll gerufen, wie gesagt ich gehe davon aus das beim Compilieren die als Parent deklarierten Nodes noch nicht vollständig geladen waren wodurch irgendwo in der dll dann wohl eine "if (!parent)" Bedinnung erfüllt war.
Das Komische ist halt man kann mit den nodes arbeiten, wie normal, ein Abfangen habe ich versucht aber nicht hinnbekommen.Habe nun einen Node in der Klasse erstellt und frage diesen von der anderen Instanz der selben Klasse ab und nehme diesen als Parent, setze dann mittels setParent diesen Node ein und habe bisher keinen segmentation fault mehr gehabt.
thx für die Hilfe
-
Nur dass das klar ist: Der Compiler hat mit deinem Problem rein gar nichts zu tun! Die Abfragen nach dem parent, das drop() usw. wird erst zur Laufzeit ausgeführt. Ein SegFault ist ein Laufzeitfehler, für den der Compiler nichts kann.
Das was du jetzt machst nennt sich "Workaround", und stellt eigentlich keine korrekte Lösung dar. Zeig doch bitte endlich mehr Code, dann kann man dir auch helfen. Ich bin mir sicher, dass du irgend etwas falsch machst.
-
Kannst du den Code auf ein komplettes Minimalbeispiel reduzieren und posten?
Hast du die Irrlicht-Referenzzählung richtig angewandt?
drop()
darfst du nur aufrufen, wenn das Objekt mit einercreate...()
-Methode erzeugt wurde oder wenn du zuvorgrab()
aufgerufen hast.