Forum: Compiler & IDEs GDB MIPS unverständliches Problem


von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Hallo,
mir ist leider kein besserer Titel eingefallen.
Baue ja immernoch an meinem MIPS1 GDB Server rum.
Der GDB kann sich auch mit dem verbinden und man kann Speicher sowie 
Register lesen/schreiben.
Breakpoints gehen auch 1a.

Nur "richtiges" Debuggen ala durchsteppen geht nicht, da macht der GDb 
total komische Sachen.
Das MIPS Programm ist mit der Option -g gebaut, damit ich Debuginfos in 
der elf habe.
Diese elf Datei gebe ich dem GDB als Option mit und mit dem GDB load 
Befehl landet der Programmcode dann auch im Prozessor.

Dann setze ich einen Breakpoint auf uart_init und lasse den GDB laufen.
Natürlich bleibt er dann beim Aufruf von uart_init stehen, das funzt 
also.
Wenn ich nun mit step durchsteppe, dann wirds komisch.
Der GDB zeigt mir manche Codezeilen doppelt an und springt auch wild in 
den Codezeilen herum:
1
(gdb) s
2
113    volatile char *uart = (char*)uarts[uart_nbr-1];
3
(gdb) s
4
132    fifo_init(fifos[(uart_nbr*2)+TX], buffers[(uart_nbr*2)+TX], FIFO_SIZE, uart_nbr, 1);
5
(gdb) 
6
113    volatile char *uart = (char*)uarts[uart_nbr-1];
7
(gdb) 
8
111  void uart_init(int uart_nbr, int baud_div, int uart_mode){
9
(gdb) 
10
113    volatile char *uart = (char*)uarts[uart_nbr-1];
11
(gdb) 
12
111  void uart_init(int uart_nbr, int baud_div, int uart_mode){
13
(gdb) 
14
132    fifo_init(fifos[(uart_nbr*2)+TX], buffers[(uart_nbr*2)+TX], FIFO_SIZE, uart_nbr, 1);
15
(gdb) 
16
111  void uart_init(int uart_nbr, int baud_div, int uart_mode){
17
(gdb) 
18
132    fifo_init(fifos[(uart_nbr*2)+TX], buffers[(uart_nbr*2)+TX], FIFO_SIZE, uart_nbr, 1);
19
(gdb) 
20
113    volatile char *uart = (char*)uarts[uart_nbr-1];

das sieht natürlich falsch aus und dabei hat die CPU noch nichtmal eine 
Funktion aufgerufen, laut "info register" hat die CPU dabei diesen ASM 
Code durchlaufen:
1
0000fe88 <uart_init>:
2
    fe88:  27bdffc8   addiu  sp,sp,-56
3
    fe8c:  2482ffff   addiu  v0,a0,-1
4
    fe90:  afb4002c   sw  s4,44(sp)
5
    fe94:  afb30028   sw  s3,40(sp)
6
    fe98:  3c140004   lui  s4,0x4
7
    fe9c:  3c130004   lui  s3,0x4
8
    fea0:  00021080   sll  v0,v0,0x2
9
    fea4:  2694d130   addiu  s4,s4,-11984
10
    fea8:  2673d120   addiu  s3,s3,-12000
11
    feac:  000418c0   sll  v1,a0,0x3

Irgendwie sieht es so aus, als würde der GDb die Debuginformationen 
ignorieren?
Denn mit den Infos würde er ja soweit gehen bis eine C Codezeile 
abgeschlossen ist.

Fällt da jemanden ein worans liegen könnte?

von Jim M. (turboj)


Lesenswert?

Der Optimizer ist an.

Der darf auch mehrere C Zeilen in eine CPU-Instruktion packen und auch 
Instruktionen lustig durcheinander würfeln - solange das Ergebnis 
dasselbe ist. Macht er gerne bei Initialisierungen von Variablen um ein 
paar Tatkzyklen zu sparen.

Verständlich wird das Ganze erst wenn man sich das Disassembly genau 
anschaut.

Der oben gezeigte Assembler Code sieht wie ein Prolog einer Funktion 
aus. Der ist schlecht einer konkreten Zeile zuzuordnen, daher nimmt er 
die allererste.

Ist "fifos_init" zufällig ein Macro?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Eigentlich (böses Wort) ist -O2 raus beim debuggen.
Aber das hat natürlich noch keiner der vorcompilierten Library gesagt, 
argh...

Danke für den Hinweis!
Hier ist das erklärt:
http://www.delorie.com/gnu/docs/gdb/gdb_17.html

Noch ne kurze andere Frage:
Wie kann ich mit dem GDB ein laufendes Programm anhalten?
In meinem GDB Server ist der Befehl dafür implementiert, aber beim GDB 
selbst ist nach continue ja kein Command Prompt mehr vorhanden und 
STRG+C sendet keinen Befehl ab.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Mw E. schrieb:
> Noch ne kurze andere Frage:
> Wie kann ich mit dem GDB ein laufendes Programm anhalten?

In eine "freestanding environment", also einem ohne OS o.ä., muss die 
Hardware (Prozessor und Debugger-Hardware) das unterstützen. In einem 
"hosted environment", also einem mit OS, Monitor, X-visor, o.ä., ist es 
oft Aufgabe des Hosts (also des OS), kann aber auch durch die HW 
erledigt bzw. unterstützt werden.

Jetzt habe ich ewig nichts mehr mit MIPS gemacht. Ich erinnere mich 
dunkel, dass die CPU einen eigenen Debug-Mode hat, den man u.a. mit 
einem Debug Interrupt erreichen kann. Dann steht die CPU und man kann in 
den Gedärmen rumwühlen.

Den Interrupt, oder was auch immer MIPS heute so verwendet, müsste durch 
deine Debugging-HW, gesteuert durch den Debugging-Server, ausgelöst 
werden.

Auf GDB-Seite ist das Ganze ein Hack, weil der Mechanismus ursprünglich 
für Unix-Programme die durch Signale abgebrochen werden können gedacht 
war. Erstmal gibt es zwei Stop-Modi, all-stop 
(https://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html) und 
non-stop - ja, non-stop ist ein Stop-Modus... (für einzelne Threads).

Wir gehen mal von all-stop aus ("set non-stop off"). Auf dem 
Remote-Interface hat GDB zwei Möglichkeiten ein all-stop auszulösen: 
https://sourceware.org/gdb/onlinedocs/gdb/Interrupts.html#Interrupts 
Entweder durch eine Telnet Break-Sequenz, oder ein Zeichensequenz wie 
0x03 (kann auch anders, z.B. als 0x03'g' konfiguriert sein).

Du könntest mit Wireshark nachsehen, was GDB an den Debug-Server sendet. 
Wenn es die Telnet Break-Sequenz ist, dann mal auf 0x03 umstellen, "set 
remotebreak off", "set remote interrupt-sequence Ctrl-C".

Wenn gar nichts gesendet wird, sieh mit "info signals" nach, wie GDB ein 
Ctrl-C (was einem SIGINT entspricht) handhabt. Wenn SIGINT nicht auf 
stop steht, dann SIGINT mittels "handle SIGINT stop" setzen.

Wenn das auch nichts hilft, dann gibt deine Shell / dein Command-Window 
Ctrl-C nicht an den GDB weiter: Shell konfigurieren oder wechseln.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Sehr nützliche Informationen, sowas müsste man sich sonst mühselig 
zusammenklamüsern.
Da ich den GDB Server, wie oben erwähnt, selber geschrieben habe, habe 
ich eh in der Hand was dieser Tut.

Mein GDB Server bekommt ja vom GDB selber nicht den Befehl, dass er die 
CPU anhalten soll. Zudem ist die MIPS CPU selber gebaut und daher hab 
ich da auch ein Debugregister, welches die CPU anhalten kann.
Wenn denn mein GDB Server diesen Befehl bekommen würde ;)
Die CPU: http://www.fritzler-avr.de/spaceage2/

Die Konsole leitet STRG+C schon weiter, der GDb zeig dann "^C" an wenn 
ich das drückeund wenn ich sehr oft STRG+C dem GDb sende, dann fragt er 
mich auch, ob ich die Verbindung zum remote target abbrechen möchte.

Wireshark brauch ich nicht (dachte ich), mein GDB Server loggt momentan 
noch den Debugoutput auf der Konsole mit. Daher weis ich ja, dass vom 
GDB kein Befehl kommt.
Aber der GDB sendet wohl doch was, dabei habe ich eigentlich auf 0x03 
geachtet.
GDB sendet dann bei mir wohl die BREAK Sequenz. Ich dachte bisher, dass 
dann ein vCont Packet kommen muss. Weil ich GDB bei der Init Seuquenz 
gesagt habe, dass mein vcont alles unterstützt.

Jedenfalls gehts jetzt, ich frage mit ioctl ab ob der TCP Socket Bytes 
hat und halte dann die CPU an und sage dem GDB, dass die CPU angehalten 
ist -> LÄUFT!

von Jim M. (turboj)


Lesenswert?

Mw E. schrieb:
> In meinem GDB Server ist der Befehl dafür implementiert, aber beim GDB
> selbst ist nach continue ja kein Command Prompt mehr vorhanden und
> STRG+C sendet keinen Befehl ab.

Der GDB selbst sollte aber auf CTRL+C oder CTRL+PAUSE reagieren, und 
entsprechend ein Kommando senden IIRC.

Mit OpenOCD hat man übrigens die Möglichkeit über ein weiters 
Telnet-Terminal den µC anzuhalten. Nur so als Idee.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das Problem is ja schon gelöst, siehe mein letzter Post.
Der zusätzliche Syscall macht den MIPS Emulator jetzt endlich fast so 
langsam wie das Original.
Miin GDB Server hat ja sein eigenes Terminal, da hätt ich das dann auch 
mit dem Anhalten implementiert wenns nach Hannes Jaegers Informationen 
nicht geklappt hätte.

Wenn beides fertig ist (GDB Server + MIPS Emulator) wirds auch 
veröffentlicht.
Läuft zwar beides schon, aber an manchen Stellen muss ich noch anfassen.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Hier dann mal der GDB Server, falls es wen interessiert:
http://www.fritzler-avr.de/spaceage2/down_software.htm

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.