Debug von Program bei dem gdb versagt



  • Hi, ich hoffe ich habe das richtige Unterforum erwischt.

    Ich habe ein C++-Programm geschrieben was irgendwie nicht so ganz korrekt ist und will es jetzt mit gdb debuggen.

    *(gdb) file test.exe
    Reading symbols from test.exe...done.
    (gdb) break main
    Breakpoint 1 at 0x401344: file test.cpp, line 6.
    (gdb) break printf
    Breakpoint 2 at 0x405d10
    (gdb) r
    Starting program: test.exe

    Program received signal SIGSEGV, Segmentation fault.
    0x10017ce5 in _end__ ()
    (gdb) bt
    #0 0x10017ce5 in _end__ ()
    Cannot access memory at address 0x40e000
    (gdb)*

    Das Programm beginnt mit includes gefolgt von main und einem printf. Es werden keine Objekte von Klassen vor main erzeugt, also wird vor main kein Code ausgeführt, aber scheinbar gibt es trotzdem ein Segfault vor main, denn es wird nie ein Breakpoint erreicht. Auch break 1 wird nicht erreicht.

    gdb funktioniert ansonsten normal, ich kann andere Programme damit debuggen.

    Kompiliert unter Win32 XP mit g++ -x c++ -Wall -pipe -g -O0.

    Wenn ich das Programm direkt starte funktioniert es, außer dass ein Thread nach dem Beenden einen Segfault auslößt (Ein Thread der ein Fenster aufgemacht, die Messagequeue bedient und es dann geschlossen hat).
    Ich habe etwas rumgesucht und gefunden, dass sowas üblicherweise passiert, wenn man den Stack kaputt gemacht hat.

    Wie kann man das jetzt debuggen? Im Code lässt sich nichts einbauen, da das Programm jenseits meines Codes verreckt. Kann man gdb dazu bringen single-step zu machen ohne run + breakpoint, sondern direkt beim Start?
    Ist ein anderer Debugger empfehlenswert, der auch mit Windowsthreads und Fenstern klarkommt?

    Vielen Dank für die Hilfe.



  • Da musst du halt traditionell debuggen: Assembler-Listing + Inhalte der Register nach jedem ASM-Befehl.
    Kann GDB auch, einfach mal die Doku checken.



  • Vielleicht kannst du sonst auch dein Programm mit Valgrind (oä) laufen lassen. Das ist speziell zum debuggen von Speicherproblemen.



  • gdb kann mir den Assemblercode anzeigen, aber das nützt mit nichts, viel zu lang um irgendwas zu finden. Schrittweise durch den Assemblercode gehen geht genausowenig wie schrittweise durch den c++-Code, weil ohne run kein step möglich ist und run sofort einen Segfault auslößt. Ich glaube fast es ist ein gdb-bug.

    Valgrind gibt es nur für Linux und das Problem steckt irgendwo in den Windowsthreads, nützt mir also nichts. An IBM's Rational Purify kommt man irgendwie nicht so richtig ran.
    DevC++ benutzt eigentlich gdb, aber irgendwie auch Insight, jedenfalls kann der das Program im Debugmodus starten, allerdings sagt er auch nicht mehr als "Segfault".

    Mir gehen die Ideen aus.



  • Dann wohl Plan B: Auf ein abstürzendes Minimalbeispiel reduzieren und wenn du auch da nix findest, einfach mal hier posten.


  • Administrator

    Gibt es eigentlich Debugversionen der Standardbibliothek beim GCC? Habe nämlich kurz sowas unter Windows probiert. Grundsätzlich gibt es ja zum Beispiel start . Nur geht dass dann gleich bis zur main . Der Einstiegspunkt wäre aber unter Windows mainCRTStartup . Man kann einen Breakpoint setzen mit break mainCRTStartup , doch leider hat er keine Debuginformationen an der Stelle.

    Grüssli



  • Zur Not gibt es nocht printf()-Debugging. Es empfiehlt sich generell seinen Code mit Debug-Ausgaben auf stderr zu versehen die optional eingeschaltet werden können. Bei interressanter Software kommt man mit einem Debugger nicht weit, wenn man nicht ungefähr weiß wo etwas schief geht.

    In deinem Fall würde ich zur Kontrolle mal einen anderen Debugger nutzen. Kannst du das Programm auch mit Visual C++ kompilieren?



  • printf-debugging geht nicht, er stürzt jenseits meines Codes ab.

    Zur Verdeutlichung:

    void meinefunktion(){
        //blablub
        printf("hier ist noch alles ok\n");
    }
    
    int main(){
        meineFunktion();
        printf("hierher kommt er nicht mehr, vorher segfault\n");
        return 0;
    }
    

    Wüsste nicht was ich da noch printen sollte. Man könnte versuchen eine Variable als Parameter zu übergeben um von der Adresse dieser Variablen vorwärts oder rückwärts gehen und ein Label hinter den Funktionsaufruf packen und nach der Rücksprungadresse/Label im Stack suchen, herausfinden wo die Adresse liegen muss und ab wann die da nicht mehr liegt.

    Inzwischen habe ich aber den Code komplett neu geschrieben und jetzt funktioniert alles, trotzdem vielen Dank.


Anmelden zum Antworten