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.