Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungLetzte ÜberarbeitungBeide Seiten der Revision | ||
software:gdb:start [2013-10-08 14:24] – abajric | software:gdb:start [2019-03-11 11:51] – graf | ||
---|---|---|---|
Zeile 6: | Zeile 6: | ||
* [[https:// | * [[https:// | ||
</ | </ | ||
- | + | ===== Hauptfunktionen des GDB ===== | |
- | Der GNU Debugger erlaubt | + | Der GNU Debugger erlaubt |
Die vier Hauptfunktionen von GDB sind: | Die vier Hauptfunktionen von GDB sind: | ||
Zeile 15: | Zeile 15: | ||
* Inhalt des Speichers ändern | * Inhalt des Speichers ändern | ||
- | ==== Handhabung ==== | ||
- | GDB ist in vielen [[http:// | ||
- | '' | + | ===== Handhabung ===== |
+ | GDB ist in vielen [[http:// | ||
+ | Das ist besonders nütztlich, um einen Segfault zu überprüfen. | ||
- | Programm starten: | + | Mehr dazu unter im [[software:gdb: |
- | '' | ||
- | Ausführung des Programms anhalten: | + | ===== Coredumps ===== |
+ | Mit Coredumps können Segfaults analysiert werden, ohne dass die Applikation im //gdb// gestartet wird. | ||
+ | Ein // | ||
+ | Es ist ebenfalls möglich, lokale Variablen nach dem Absturz zu untersuchen. | ||
- | '' | + | Mehr dazu unter unter [[software: |
- | Programm beenden: | ||
- | '' | + | ===== STABS ===== |
+ | STABS (symbol tables) ist das Format in welchem das Program für den Debugger beschrieben wird. Der GCC Compiler kompiliert C-Programme (.c) in Assembler-Programme (.s), welche vom Assembler in Objekt-Dateien (.o) kompiliert werden, die dann vom Linker und anderen Objekt-Dateien zu einem ausführbarem Programm verlinkt werden. | ||
- | GDB beenden: | + | Mit der Option ' |
- | '' | + | Beispiel: [[https:// |
- | Alle GDB Befehle können mit der GDB-Hilfefunktion aufgelistet werden: | + | ===== Remote Debugging ===== |
- | '' | + | <box 30% right green > |
+ | {{: | ||
+ | </ | ||
+ | GDB kann auch Programme debuggen, die nicht lokal ausgeführt werden. Auf dem Target muss aber ein RSP-Server lauften, der mit dem GDB kommunizieren kann. Die Kommunikation läuft über das [[http:// | ||
- | ==== STABS ==== | ||
- | STABS (symbol tables) ist das Format in welchem das Program für den Debugger beschrieben wird. Der GCC Compiler kompiliert C-Programme (.c) in Assembler-Programme (.s), welche vom Assembler in Objekt-Dateien (.o) kompiliert werden, die dann vom Linker und anderen Objekt-Dateien zu einem ausführbarem Programm verlinkt werden. | ||
- | Mit der Option '-g' des GCC Compilers | + | ===== Beispiel mit MPC5200 ===== |
+ | |||
+ | |||
+ | ==== Grundsätzlicher Aufbau ==== | ||
+ | |||
+ | In der Zukunft sollte der Deep-Compiler zwei Files generieren. Das Image-File, welches direkt auf den MPC5200 geladen und ausgeführt | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Im ELF-File stehen die Debug-Information | ||
+ | |||
+ | |||
+ | |||
+ | ==== Java Code ==== | ||
+ | |||
+ | Um das Beispiel noch zu vereinfachen wird eine Endlos-Schleife ans Ende der //reset()//-Methode eingefügt: | ||
+ | |||
+ | < | ||
+ | static void reset() { | ||
+ | int stackOffset = US.GET4(sysTabBaseAddr + stStackOffset); | ||
+ | int stackBase = US.GET4(sysTabBaseAddr + stackOffset + 4); | ||
+ | int stackSize = US.GET4(sysTabBaseAddr + stackOffset + 8); | ||
+ | US.PUTGPR(1, stackBase + stackSize - 4); // set stack pointer | ||
+ | int kernelClinitAddr = US.GET4(sysTabBaseAddr + stKernelClinitAddr); | ||
+ | US.PUTSPR(SRR0, | ||
+ | US.PUTSPR(SRR1, | ||
+ | // | ||
+ | |||
+ | int x = 4; | ||
+ | x ^= 0x55; | ||
+ | |||
+ | US.PUTGPR(R27, | ||
+ | while (true); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Assembler Code ==== | ||
+ | |||
+ | Der Assembler-Code (test.S) sieht wie folgt aus: | ||
+ | |||
+ | < | ||
+ | .org 0x400100 | ||
+ | reset: | ||
+ | li r2, 16388 | ||
+ | lwz r4, 0(r2) | ||
+ | addi r2, r4, 16384 | ||
+ | addi r3, r2, 4 | ||
+ | lwz r5, 0(r3) | ||
+ | addi r2, r4, 16384 | ||
+ | addi r3, r2, 8 | ||
+ | lwz r4, 0(r3) | ||
+ | add r2, r5, r4 | ||
+ | addi r3, r2, -4 | ||
+ | mr r1, r3 | ||
+ | li r2, 16396 | ||
+ | lwz r4, 0(r2) | ||
+ | mr r0, r4 | ||
+ | mtspr SRR0, | ||
+ | li r2, 14338 | ||
+ | mr r0, r2 | ||
+ | mtspr SRR1, | ||
+ | li r2, 4 | ||
+ | xori r3, r2, 0x55 | ||
+ | xoris r3, r3, 0x0 | ||
+ | mr r27, r2 | ||
+ | b 0 | ||
+ | </ | ||
+ | |||
+ | Kompiliert wird mit folgendem Befehl: | ||
+ | |||
+ | < | ||
+ | $ powerpc-linux-gnu-as -mppc32 -mregnames -be test.S | ||
+ | </ | ||
+ | |||
+ | Das ELF-File //a.out// wird erstellt. Dieses File kann durch folgenden Befehl disassembliert werden: | ||
+ | |||
+ | < | ||
+ | $ powerpc-linux-gnu-objdump -d -EB -G -mpowerpc a.out | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Assembler Code mit STABS ==== | ||
+ | |||
+ | Der Assembler-Code (test.S) mit den Debug-Informationen sieht wie folgt aus: | ||
+ | |||
+ | < | ||
+ | .include " | ||
+ | |||
+ | .stabs " | ||
+ | .stabs " | ||
+ | |||
+ | .data | ||
+ | .org 0x100000 | ||
+ | .stabs " | ||
+ | .global targetCommand | ||
+ | targetCommand: | ||
+ | .int 0 | ||
+ | |||
+ | .org 0x400100 | ||
+ | .stabs "/ | ||
+ | .stabs " | ||
+ | .text | ||
+ | Ltext0: | ||
+ | |||
+ | reset: | ||
+ | .stabn N_SLINE, 0, 38, LM1 | ||
+ | LM1: | ||
+ | li r2, 16388 | ||
+ | lwz r4, 0(r2) | ||
+ | addi r2, r4, 16384 | ||
+ | addi r3, r2, 4 | ||
+ | lwz r5, 0(r3) | ||
+ | addi r2, r4, 16384 | ||
+ | addi r3, r2, 8 | ||
+ | lwz r4, 0(r3) | ||
+ | add r2, r5, r4 | ||
+ | addi r3, r2, -4 | ||
+ | .stabn N_SLINE, 0, 41, LM5 | ||
+ | LM6: | ||
+ | mr r1, r3 | ||
+ | li r2, 16396 | ||
+ | lwz r4, 0(r2) | ||
+ | mr r0, r4 | ||
+ | mtspr SRR0, | ||
+ | li r2, 14338 | ||
+ | mr r0, r2 | ||
+ | mtspr SRR1, | ||
+ | .stabn N_SLINE, 0, 47, LM4 | ||
+ | LM4: | ||
+ | li r2, 4 | ||
+ | .stabs " | ||
+ | .stabn N_SLINE, 0, 48, LM5 | ||
+ | LM5: | ||
+ | xori r3, r2, 0x55 | ||
+ | .stabs " | ||
+ | xoris r3, r3, 0x0 | ||
+ | .stabn N_SLINE, 0, 50, LM2 | ||
+ | LM2: | ||
+ | mr r27, r2 | ||
+ | .stabs " | ||
+ | .stabn N_SLINE, 0, 51, LM3 | ||
+ | LM3: | ||
+ | b 0 | ||
+ | |||
+ | .stabs " | ||
+ | .stabn N_SLINE, 0, 37, reset | ||
+ | .stabn N_LBRAC, 0, 0, LM1 | ||
+ | .stabn N_RBRAC, 0, 0, LM3 | ||
+ | </ | ||
+ | |||
+ | Im File // | ||
+ | |||
+ | < | ||
+ | # non-stab symbol types | ||
+ | .set N_UNDF, | ||
+ | .set N_EXT, | ||
+ | .set N_ABS, | ||
+ | .set N_TEXT, | ||
+ | .set N_DATA, | ||
+ | .set N_BSS, | ||
+ | .set N_FN_SEQ, | ||
+ | .set N_INDR, | ||
+ | .set N_COMM, | ||
+ | .set N_SETA, | ||
+ | .set N_SETT, | ||
+ | .set N_SETD, | ||
+ | .set N_SETB, | ||
+ | .set N_SETV, | ||
+ | .set N_WARNING, | ||
+ | .set N_FN, | ||
+ | |||
+ | # stab symbol types | ||
+ | .set N_GSYM, | ||
+ | .set N_FNAME, | ||
+ | .set N_FUN, | ||
+ | .set N_STSYM, | ||
+ | .set N_LCSYM, | ||
+ | .set N_MAIN, | ||
+ | .set N_ROSYM, | ||
+ | .set N_PC, | ||
+ | .set N_NSYMS, | ||
+ | .set N_NOMAP, | ||
+ | .set N_MAC_DEFINE, | ||
+ | .set N_OBJ, | ||
+ | .set N_MAC_UNDEF, | ||
+ | .set N_OPT, | ||
+ | .set N_RSYM, | ||
+ | .set N_M2C, | ||
+ | .set N_SLINE, | ||
+ | .set N_DSLINE, | ||
+ | .set N_BSLINE, | ||
+ | .set N_BROWS, | ||
+ | .set N_DEFD, | ||
+ | .set N_FLINE, | ||
+ | .set N_EHDECL, | ||
+ | .set N_MOD2, | ||
+ | .set N_CATCH, | ||
+ | .set N_SSYM, | ||
+ | .set N_ENDM, | ||
+ | .set N_SO, | ||
+ | .set N_LSYM, | ||
+ | .set N_BINCL, | ||
+ | .set N_SOL, | ||
+ | .set N_PSYM, | ||
+ | .set N_EINCL, | ||
+ | .set N_ENTRY, | ||
+ | .set N_LBRAC, | ||
+ | .set N_EXCL, | ||
+ | .set N_SCOPE, | ||
+ | .set N_RBRAC, | ||
+ | .set N_BCOMM, | ||
+ | .set N_ECOMM, | ||
+ | .set N_ECOML, | ||
+ | .set N_WITH, | ||
+ | .set N_NBTEXT, | ||
+ | .set N_NBDATA, | ||
+ | .set N_NBBSS, | ||
+ | .set N_NBSTS, | ||
+ | .set N_NBLCS, | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Beschreibung der STABS ==== | ||
+ | |||
+ | Online Doku von GDB: | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | === Definition von Typen === | ||
+ | ([[https:// | ||
+ | Type 1 = void und Type 2 = int. | ||
+ | |||
+ | < | ||
+ | .stabs " | ||
+ | .stabs " | ||
+ | </ | ||
+ | |||
+ | === Definition von globalen Variablen === | ||
+ | |||
+ | ([[https:// | ||
+ | Variable | ||
+ | |||
+ | < | ||
+ | .data | ||
+ | .org 0x100000 | ||
+ | .stabs " | ||
+ | .global targetCommand | ||
+ | targetCommand: | ||
+ | .int 0 | ||
+ | </ | ||
+ | |||
+ | === Definition vom Java-Sourcecode === | ||
+ | |||
+ | ([[https:// | ||
+ | Der erste STABS mit N_SO ist der Build-Ordner. Der Zweite ist der relative Pfad zum Source-File. | ||
+ | |||
+ | < | ||
+ | .org 0x400100 | ||
+ | .stabs "/ | ||
+ | .stabs " | ||
+ | .text | ||
+ | Ltext0: | ||
+ | </ | ||
+ | |||
+ | === Definition von Zeilennummern === | ||
+ | |||
+ | ([[https:// | ||
+ | |||
+ | < | ||
+ | reset: | ||
+ | .stabn N_SLINE, 0, 38, LM1 | ||
+ | LM1: | ||
+ | |||
+ | ... | ||
+ | |||
+ | .stabn N_SLINE, 0, 41, LM5 | ||
+ | LM6: | ||
+ | |||
+ | ... | ||
+ | |||
+ | .stabn N_SLINE, 0, 47, LM4 | ||
+ | LM4: | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | === Definition von Registervariablen === | ||
+ | ([[https:// | ||
+ | Registervariablen müssen immer im gleichen Register bleiben. (" | ||
+ | |||
+ | < | ||
+ | .stabs " | ||
+ | </ | ||
+ | |||
+ | |||
+ | === Definition von Funktionen === | ||
+ | |||
+ | ([[https:// | ||
+ | |||
+ | < | ||
+ | .stabs " | ||
+ | .stabn N_SLINE, 0, 37, reset | ||
+ | .stabn N_LBRAC, 0, 0, LM1 | ||
+ | .stabn N_RBRAC, 0, 0, LM3 | ||
+ | </ | ||
+ | |||
+ | ==== Debuggen mit GDB ==== | ||
+ | |||
+ | Damit ein PowerPC Target debugged werden kann muss GDB mit PowerPC Support installiert werden: | ||
+ | |||
+ | < | ||
+ | $ sudo apt-get install gdb-multiarch | ||
+ | </ | ||
+ | |||
+ | Bevor GDB gestarted wird, muss das Image-File auf den MPC5200 geladen werden: | ||
+ | |||
+ | < | ||
+ | $ telnet bdi3000inf01 | ||
+ | pcm5200io> | ||
+ | pcm5200io> | ||
+ | </ | ||
+ | |||
+ | GDB starten: | ||
+ | < | ||
+ | $ gdb-multiarch | ||
+ | </ | ||
+ | |||
+ | PowerPC Architektur auswählen: | ||
+ | |||
+ | < | ||
+ | (gdb) set arch powerpc: | ||
+ | </ | ||
+ | |||
+ | ELF-File mit Debug-Informationen auswählen: | ||
+ | |||
+ | < | ||
+ | (gdb) file ./a.out | ||
+ | </ | ||
+ | |||
+ | GDB mit Abatron BDI3000 verbinden: | ||
+ | |||
+ | < | ||
+ | (gdb) target remote bdi3000inf01: | ||
+ | </ | ||
+ | |||
+ | GDB TUI aktivieren und Layout umstellen: | ||
+ | |||
+ | < | ||
+ | (gdb) layout split | ||
+ | (gdb) focus cmd | ||
+ | </ | ||
+ | |||
+ | Alternativ kann ein File (gdb.cmd) mit diesen GDB-Kommandos erstellt werden: | ||
+ | |||
+ | < | ||
+ | set arch powerpc: | ||
+ | file ./a.out | ||
+ | target remote bdi3000inf01: | ||
+ | layout split | ||
+ | focus cmd | ||
+ | </ | ||
+ | |||
+ | Beim Ausführen von GDB muss dieses File angegeben werden, damit alle Kommandos im File ausgeführt werden: | ||
+ | |||
+ | < | ||
+ | $ gdb-multiarch -x ./gdb.cmd | ||
+ | </ | ||
+ | |||
+ | Mit dem folgenden Befehl kann der Java-Sourcecode angezeigt werden: | ||
+ | |||
+ | < | ||
+ | (gdb) list | ||
+ | </ | ||
+ | |||
+ | Mit dem folgenden Befehl wird eine Assembler-Instruktion ausgeführt: | ||
+ | |||
+ | < | ||
+ | (gdb) stepi | ||
+ | </ | ||
+ | |||
+ | Mit dem folgenden Befehl wird Code ausgeführt, | ||
+ | |||
+ | < | ||
+ | (gdb) next | ||
+ | </ | ||
+ | |||
+ | Mit dem folgenden Befehl wird eine definierte Variable ausgegeben: | ||
+ | |||
+ | < | ||
+ | (gdb) print x | ||
+ | </ | ||
+ | |||
+ | Mit dem folgenden Befehl wird eine definierte Variable geändert: | ||
+ | |||
+ | < | ||
+ | (gdb) set var x = 12345 | ||
+ | </ | ||
- | ==== Remote Debugging ==== | + | Mit dem folgenden Befehl |
- | GDB kann auch Programme debuggen, die nicht lokal ausgeführt | + | |
+ | < | ||
+ | (gdb) set var *0x100000 = 12345 | ||
+ | </ |