g++ und -fstack-protector, gibt es beim Kompilieren etwas zu beachten?



  • Hallo Leute,

    weiß jemand zufällig, ob es beim Bauen einer Applikation mit g++ und zusätzlichen Parametern -fstack-protector und -fstack-protector-all irgendwas spezielles zu beachten gibt?
    Ich habe folgendes Problem. Ich soll in einer Applikation nach einem Bug suchen, bei dem die Applikation mit einem SIGSEGV (Segmentation fault) abstürzt. Die Applikation läuft auf einem eingebetteten System mit einer ARM CPU unter Angstrom Linux und verwendet Qt 4.7.4.
    Die Applikation baue ich unter anderem mit folgenden Flags:

    -O0 -ggdb
    

    und starte sie auf dem Target mit gdbserver und verbinde mich damit mit gdb am PC. Das Problem ist leider, dass gdb nicht alle Symbole kennt, z.B. die Bibliotheken auf dem Target sind "gestrippt", Qt 4.7.4 Bibliotheken müssen auch für Release gebaut werden aus verschiedenen Gründen, d.h. gibt es ein SIGSEGV und schaut man sich mit gdb den Backtrace an, sieht man meist lauter Fragezeichen und Adressen, mit denen ich momentan nichts anfangen kann. Zusätzlich gibt es noch etwa ein Dutzend Threads - schaut man sich deren Backtrace an, sieht man auch nur lauter Fragezeichen.
    Baue ich die Applikation mit -fstack-protector Flags:

    -O0 -ggdb -fstack-protector -fstack-protector-all
    

    stürzt die Applikation scheinbar zufällig an verschiedenen Stellen im Code sofort ab! Normalerweise ist der Absturz selten (einmal in 3 Stunden oder so)... die einzige Ausgabe ist eben SIGSEGV (Segmentation fault) und ich komme auch hier mit gdb nicht weiter, wegen zum einen fehlender Symbole und zum anderen immer zufällige Stellen, an denen der Absturz passiert.
    Muss man vielleicht beim Bauen mit -fstack-protector Flags irgendwas beachten? Hat jemand so was in der einen oder anderen Form erlebt...

    Grüße,
    abc.w



  • Tretet der Fehler nur beim Eingebetteten System auf?
    Wenn nicht kannst du ja mal Qt im Debug Modus auf deinem Haupt-PC kompilieren und dort mal 3h laufen lassen.

    Oder geht das auch nicht?

    Ansonsten würde ich, falls der Code nicht allzu groß ist, Debug-Ausgaben einfügen, welche mich näher zur Stelle des Absturzpunktes bringen.



  • Der Fehler tritt nur auf dem Target auf. Einen Teil der Applikation wie GUI kann man auch am PC für PC bauen und ausführen lassen, aber da tritt der Absturz nicht auf. Erst auf dem Target, wo alle Komponenten der Applikation aktiv werden, tritt es auf.
    Mit Debug-Ausgaben allein komme ich momentan auch nicht weiter 😞



  • Ganz normaler Speicherzugriffsfehler. Du hast festgestellt, dass der Debugger nicht hilft. D.h. musst du selbst den Code anschauen.



  • Hallo,

    falls es noch jemand interessiert, diese rätselhaften Abstürze der Applikation nach dem Bauen mit -fstack-protector Flags lagen aus welchen Gründen auch immer an den Bibliotheken. Sobald irgendeine Bibliothek, die vorher ebenfalls mit -fstack-protector Flags gebaut wurde, geladen und irgendeine Funktion daraus ausgeführt wurde, gab es einen SIGSEGV Segmentation Fault. Warum - bleibt wohl für immer ein Rätsel. Es sei denn, jemand kann dazu etwas sagen - Kommentare gerne willkommen 🙂
    Baut man die Applikation mit -fstack-protector Flags und die zugehörigen Bibliotheken ohne, gibt es keine derartigen Probleme.

    Grüße,
    abc.w



  • lagen aus welchen Gründen auch immer an den Bibliotheken [..] Warum - bleibt wohl für immer ein Rätsel

    Dazu muesste man mal wissen, was -fstack-protector macht. Im I-Net finde ich keine Informationen dazu.



  • Der Compiler generiert in den Funktionen zusätzlichen Code, der am Anfang der Funktion auf dem Stack eine "magic number" ablegt und am Ende der Funktion prüft, ob diese "magic number" noch heil ist. Wenn ja - die Funktion wird normal verlassen, wenn nein - vor dem Verlassen wird eine stack_chk_fail() Funktion aufgerufen. So ungefähr steht es im Manual von gcc und ich habe es grade ausprobiert, main.cpp:

    void func()
    {
    }
    

    gebaut mit g++ 4.4.0:

    g++ -c main.cpp -o main.S -O0 -fstack-protector -fstack-protector-all -S
    

    und main.S angeguckt mit

    cat main.S | c++filt
    

    und die Ausgabe:

    .file   "main.cpp"
            .text
    .globl func()
            .def    func(); .scl    2;      .type   32;     .endef
    func():
    LFB0:
            pushl   %ebp
    LCFI0:
            movl    %esp, %ebp
    LCFI1:
            subl    $24, %esp
    LCFI2:
            movl    ___stack_chk_guard, %eax
            movl    %eax, -12(%ebp)
            xorl    %eax, %eax
            movl    -12(%ebp), %eax
            xorl    ___stack_chk_guard, %eax
            je      L3
            call    ___stack_chk_fail
    L3:
            leave
            ret
    LFE0:
            .def    ___stack_chk_fail;      .scl    2;      .type   32;     .endef
    

    So ähnlich müsste es auch auf der ARM-Architektur aussehen - wenn ich bloss ARM Assembler gut lesen könnte und Zeit dazu hätte.


Anmelden zum Antworten