Debugging ohne Debug in Visual C++ 2010



  • Hallo Leute,
    weiß nicht ob das hier der richtige Thread ist, sorry...

    Meine Aufgabe ist es, die Funktionalität einer Game-Engine zu erweitern. Dazu muss ich Klassen programmieren, die von bestimmten gegebenen Klassen ableitet und das ganze wird dann als DLL in die Engine geladen. Wie im Titel schon erwähnt mache ich das mit Visual C++ 2010.

    Innerhalb meiner Funktionen rufe ich meinerseits wieder Funktionen von Drittherstellern auf (z.B. einer KI-Engine oder eines Offscreen-Browser-Renderers)

    Ich habe das Problem dass die Game-Engine manchmal abstürzt wenn meine DLLs im Einsatz sind. Ich würde gerne herausfinden wo genau der Absturz passiert.
    Ich kann mit Visual C++ 2010 leider nicht so richtig debuggen. Ich würde ja gerne Debug-DLLs erzeugen und mit der Game-Engine laden aber diese Engine akzeptiert diese Debug-DLLs nicht immer (manchmal schon, aber in meinem konkreten Fall leider nicht). Das mag daran liegen dass ich schon von den Drittherstellern keine entsprechenden Debug-Bibliotheken habe.

    Im Moment habe ich innerhalb aller von mir programmierten Funktionen den gesamten Code in try-catch eingebettet. Sofern ich informiert bin, sollte jede Exception abgefangen werden wenn ich catch(...) verwende. Innerhalb des Catch-Blocks schreibe ich was in die Log-Datei bzw. ich könnte auch ne MessageBox anzeigen lassen.

    Leider stürzt mir die Engine ab und ich habe hinterher eine leere Log-Datei bzw. keine MessageBox wurde angezeigt.

    Jetzt hab ich so ein schweres Geschütz aufgefahren und komme trotzdem nicht weiter.

    Kann mir vielleicht jemand sagen was ich noch versuchen könnte? Eine gängige/bewährte Praxis bei sowas? Ich wäre schon froh wenn ich wenigstens wüsste in welcher meiner Funktion der Absturz passiert. Dann lässt sich vielleicht auch herausfinden ob es sein kann, dass die aufgerufene Funktion eines Drittherstellers möglicherweise den Absturz verursacht...

    MfG



  • Verwendest du eine professionelle Logging-Library oder hast du dir selbst etwas zusammengeschnitzt? Dann kann es sein, dass Dinge verloren gehen wenn du nicht geflushed hast.

    MfG SideWinder



  • Man kann auch Release Builds debuggen. In den Projekt Settings kannst du einstellen, dass er Debuginfos generieren soll, falls nötig noch Optimierungen ausschalten. Die gängige Praxis ist wohl: Debug > Exceptions > Häkchen setzen... Prozess vom VS aus starten oder Debugger attachen...



  • Danke für die Antworten erst mal.

    @SideWinder: Ich habe mir selber was zusammengebaut, aber ich schließe die Datei nachdem ich was raus geschrieben habe. Dann muss ich ja nicht flushen oder?

    @HighendCoder: Hab ich jetzt gemacht, aber mehr als eine Hex-Adresse wo der Fehler passiert bekomme ich nicht heraus. Diese Adresse gehört wohl zum Speicherbereich der Game-Engine selbst (der .exe Datei, die meine DLL lädt).

    Und der Exceptioncode ist 0xC0000005L, also EXCEPTION_ACCESS_VIOLATION, wenn ich mich nicht irre.

    Ich hab halt leider gar keine Ahnung wie man richtig debugt. Gibt es keine Tools die einem sagen wie die Funktion heißt, die dort aufgerufen wurde? Vielleicht eins von diesen Windows-Sysinternals? Da gibts so viele, ich wüsste nicht welches das richtige ist...



  • Ist ein wenig Low-Tech, aber du kannst ja den Codepfad mit Ausgaben (cout oder Filestream) pflastern und dann siehst du ja, an welcher Stelle das Ganze aufhört.
    Aber ein ordentlicher Debugbuild und dann ein Backtrace wäre schon schöner 😉





  • @bmario: Wenn ich dich richtig verstehe, dann hab ich genau das schon veruscht. Ich schreib in die Log-Datei wenn eine meiner selber programmierten Funktionen beginnt und wenn sie endet. Das Ende meiner Funktionen wird immer erreicht. Der Fehler passiert irgendwo anders 😞

    @Hi: Ich schau mir das mal an. Schade dass es nur shareware ist 😞

    Vielen Dank allen Antwortern!



  • Ich hab halt leider gar keine Ahnung wie man richtig debugt.

    Mach die Projekteinstellungen auf.
    Wähle die Release Config aus.
    Mach die "Configuration Properties" auf.

    Geh zu "C++/Optimization" und stelle dort ein:

    Optimization = Disabled
    Omit Frame Pointers = No
    Whole Program Optimization = No

    Weiters in "C++/General":

    Debug Information Format = Program Database

    Und unter "Linker/Debugging":

    Generate Debug Info = Yes

    Dann baust du das ganze Projekt neu (Rebuild All).

    Jetzt musst du nur noch das Programm im Debugger starten. Dazu kannst du, wieder in den Projekteinstellungen, wieder die "Configuration Properties", und dort unter "Debugging", einstellen:
    Command = .exe die er starten soll
    Command Arguments = evtl. nötige Kommandline-Parameter für die .exe
    Working Directory = in welchem Verzeichnis er die .exe starten soll

    Und dann drückst du einfach "Play" und wartest was passiert 🙂

    Alternativ kannst du dich auch auf nen laufenden Prozess draufhängen. Das geht über das Menu "Debug", Punkt "Attach to Process...".

    ----

    Wenn dann während der Debug Session eine Access Violation stattfindet, dann hält er dir im Debugger an statt einfach zu crashen, und du siehst genau was die Access Violation ausgelöst hat.



  • @hustbaer: Danke, aber das hab ich genauso gemacht. Ich habe genau diese Einstellungen vorgenommen, die GameEngine mit meiner DLL gestartet und dann diesen Prozess angehängt. Auf dem Aufrufstack liegt die .exe der Game-Engine ganz oben. Ich interpretiere das so, dass eben in der .exe der GameEngine der Fehler passiert und nicht in meiner DLL. Der Debugger sagt mir aber dass er für die .exe und einige andere DLLs, die nicht von mir stammen, die entsprechende .pdb Datei nicht finden konnte (die .pdb-Dateien hab ich auch gar nicht) und daher keine näheren Informationen angezeigt werden können.



  • Wenn irgendwo im Callstack deine DLL steht, kannst du da schauen, ob du irgendwas mit falschen Parametern aufrufst. Wenn nicht, kann es sein, dass du vorher Objekte übergeben hast, die du zu früh frei gibts oder löscht?

    Wenn du dir sicher bist, dass du alles richtig machst, wende dich mit einem Reproducer an den Hersteller der Engine.


Anmelden zum Antworten