Forum: Compiler & IDEs GDB Remote Protokoll MIPS


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Programmiere grade einen MIPS Emulator damit das Projekt hier auch mal 
von Zuhause weiterlaufen kann:
http://www.fritzler-avr.de/spaceage2/
Das Gerät spricht zwar den MIPS1 Befehlsatz aber unter der Haube ist es 
dann doch anders, zB anderes Exceptionhandling.

Der Emulator läuft, jetzt soll er mit dem GDB reden können.
Das geht auch gut bis der GDB die Register abfragt:
"warning: Invalid remote reply: 5"
Und der GDB hängt sich komplett auf.
Die Register sende ich in der Reihenfolge wie es hier steht:
https://sourceware.org/gdb/onlinedocs/gdb/MIPS-Register-packet-Format.html#MIPS-Register-packet-Format
Also:
"All registers are transferred as thirty-two bit quantities in the 
order: 32 general-purpose; sr; lo; hi; bad; cause; pc; 32 floating-point 
registers; fsr; fir; fp."

Als wüsste er nicht welche Register kommen und eine xml Config kann ich 
dem GDB nicht geben, da er behaptet, dass der XML Parser zur Compilezeit 
nicht dabei war, aber bei configure habe ich ihm "--with-libexpat" 
mitgegeben.
Eigentlich sollte der GDB sich die config vom GDb Server holen, aber 
solch ein Befehl wird vor dem Register lesen nicht gesendet vom GDB.
HÄ?

Also wie bekomm ich jetzt den Registerlesebefehl so gebaut, dass der GDB 
das frisst?

Hier noch die Kommunikation:
alloziere MIPS CPU Speicher
fülle MIPS CPU Speicher (256532 bytes)
GDB: warte auf eingehende Verbindung vom GDB Client auf 0.0.0.0:2842
GDB: eingehende Verbindung von: 127.0.0.1:4510

(GDB ->) 
$qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfo 
rk-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+#df
(GDB <-) +
GDB command: qSupported
(GDB <-) $PacketSize=4076#01

(GDB ->) $vMustReplyEmpty#3a
(GDB <-) +
GDB command: vMustReplyEmpty
(GDB <-) $#00

(GDB ->) $Hg0#df
(GDB <-) +
GDB command: Hg0
(GDB <-) $OK#9a

(GDB ->) $qTStatus#49
(GDB <-) +
GDB command: qTStatus
(GDB <-) $#00

(GDB ->) $?#3f
(GDB <-) +
GDB command: ?
(GDB <-) $5#35

(GDB ->) $qfThreadInfo#bb
(GDB <-) +
GDB command: qfThreadInfo
(GDB <-) $m 0#bd

(GDB ->) $qsThreadInfo#c8
(GDB <-) +
GDB command: qsThreadInfo
(GDB <-) $l#6c

(GDB ->) $Hc-1#09
(GDB <-) +
GDB command: Hc-1
(GDB <-) $OK#9a

(GDB ->) $qC#b4
(GDB <-) +
GDB command: qC
(GDB <-) $#00

(GDB ->) $qAttached#8f
(GDB <-) +
GDB command: qAttached
(GDB <-) $0#30

(GDB ->) $qOffsets#4b
(GDB <-) +
GDB command: qOffsets
(GDB <-) $Text=0;Data=0;Bss=0;#3f

(GDB ->) $Hg0#df
(GDB <-) +
GDB command: Hg0
(GDB <-) $OK#9a

(GDB ->) $g#67
(GDB <-) +
GDB command: g
(GDB <-) 
$00000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000000000 
000000000#80

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Mw E. schrieb:

> Als wüsste er nicht welche Register kommen und eine xml Config kann ich
> dem GDB nicht geben, da er behaptet, dass der XML Parser zur Compilezeit
> nicht dabei war, aber bei configure habe ich ihm "--with-libexpat"
> mitgegeben.

Du musst auch die libexpat (mitsamt Headern) daliegen haben, damit
er das wirklich nimmt.

Hilft dir aber (wie du schon bemerkt hast) für die Register nicht
weiter.  Ist nur nützlich, um die Speicherkonfiguration vom Target
rüberzureichen (Flash, RAM).

Prinzipiell denke ich, dass dein Prinzip richtig ist, aber schau doch
einfach mal im GDB selbst nach, was er bei MIPS für die Register
erwartet.

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


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
der Fehler war dann doch einfacher als Gedacht und lag nicht am Register 
auslesen.
Die Reihenfolge im Link ist zudem korrekt.

Die Verwirrung kam, weil der Fehler vom GDB erst nach dem Register 
einlesen ausgegeben wurde.

Der Fehler war aber hier:
(GDB ->) $?#3f
(GDB <-) +
GDB command: ?
(GDB <-) $5#35

Die Antwort muss $S05# lauten.
Dann ist der GDB glücklich und ich kann Register/RAM lesen/schreiben.
Mehr hab ich bisher auch noch nicht implementiert.

Aber es gibt ein neues Problem.

Mit "info Register" kann ich mir die Register ansehen
und mit set $s0 = 4000 Register setzen.

Zum setzen nimmt er den P Befehl, also P1d=wert (Beispielhaft).
Danach ließt der GDB mit g wieder alle Register aus.

Nach einer Weile rumspielen (Register setzen und lesen) fängt der GDB an 
den M Befehl zum Register setzen zu nutzen, das ist natürlich falsch.
Zum Auslesen der Register nutzt er dann auch auf einmal den m Befehl.
Dann steht bei info register natürlich nur Müll, weil er Speicher 
ausließt.

Muss das heute Abend mal nochmal nachstellen.
Dann gibts mehr Infos.

Villeicht weis da aber wer jetzt schon genaueres?
GDB 7.12 nutze ich für mips-elf

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


Bewertung
0 lesenswert
nicht lesenswert
Also das Verhalten, mit dem Registerfail, konnte ich bisher nicht 
reproduzieren.

Kleiner Rant am Rande zu Memory Breakpoints:
Bei einem Memory Breakpoint überschreibt man den Befehl mit etwas was 
die CPU zu einer Exception veranlasst, wenn diese dort vorbeikommt.
GDB ließt den Befehl aus und sagt mir dann ich soll da doch nen 
Membreakpoint hinsetzen (Z0)

(GDB ->) $m200,4#5f
(GDB <-) +
(GDB <-) $3c040003#bd

(GDB ->) $Z0,200,4#a8
(GDB <-) +
(GDB <-) $OK#9a

Dann lass ich die CPU laufen und der Breakpoint wird erreicht.
Danach nehme ich den Step Befehl und vorher sagt mir GDB nur per z0, 
dass ich den Breakpoint rausnehmen soll.
Sagt mir aber nicht wie das word vorher dort Aussah, darum soll ich mich 
also selber kümmern gnarf

(GDB ->) $z0,200,4#c8
(GDB <-) +
(GDB <-) $OK#9a

(GDB ->) $s#73
(GDB <-) +

Beim Emulator kann ich ja einfach das Binary nochmal aufmachen und 
wieder das Word reinkopieren.
Aber später soll der GDB Server dann auch per USB mit den Hardware 
Debugregistern des TTL MIPS reden.

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


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So ziemlich jede GDB GUI mag wohl den MIPS GDB nicht, hab ich 
rausgefunden.
kdbg, ddd usw und auch Code::Blocks.
Es geht alles bis auf Register anzeigen.

Das liegt wohl daran wie der MIPS GDB die Register anzeigt, denn es sind 
immer 32 Register.
Deswegen zeigt er diese in mehreren Zeilen horizontal an.
Andere GDB Versionen (x86/ARM) zeigen die Register vertikal an.
(siehe Bilder im Anhang)

Daher muss ich das wohl im Sourcecode des GDB ändern, nur finde ich die 
Stelle nicht wo dies getan wird.
Hat hier jemand Ahnung vom GDB Sourcecode und kann mir sagen welche 
Datei für MIPS die Register printed beim Befehl "info register"?
Da das intern alles mit Funktionspointern arbeitet um neue Architekturen 
hinzufügen zu können ist das recht unübersichtlich.

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


Bewertung
0 lesenswert
nicht lesenswert
Hat da keiner eine Idee in welcher C Datei der GDB die MIPS Register auf 
der Konsole ausspuckt?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Mein "grep -R" meint, dass es in gdb/mips-tdep.c ist,
mips_print_registers_info(), welches in Folge print_gp_register_row()
aufruft.

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


Bewertung
0 lesenswert
nicht lesenswert
Dann is mein grep doof, habe nämlich nach print_register gesucht.
Danke schonmal, dann Spiel ich heute Abend damit rum.

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


Bewertung
0 lesenswert
nicht lesenswert
Da kram ich mal meinen alten Thread raus, weil ich wieder eine Frage 
habe zum Protokoll.

Momentan baue ich den GDB Server in den Debugger des MIPS TTL ein.
Somit soll nicht mehr nur das Programm im Simulator debuggt werden, 
sondern jetzt auch mal die echte Hardware!

Bisher kann ich Register/Speicher lesen/schreiben.
Somit kann ich jetzt per GDB das programm laden und vergleichen.
Beim Vergleichen kann ja das qCRC genutzt werden.

Das funktioniert auch bei den kleinen Sections, aber bei einer 70kbyte 
.text Section gibts einen Fehler.
Ich vermute, dass dem GDB die Antwort zu lange dauert.
Gibt es irgendein keepalive, dass man zwischendrinn senden kann?

GDB Ausgabe:
Loading section reset, size 0x10 lma 0x0
Loading section eirq, size 0x8 lma 0x100
Loading section ovw, size 0x4 lma 0x120
Loading section undef, size 0x4 lma 0x140
Loading section sysc, size 0x4 lma 0x160
Loading section break, size 0x4 lma 0x180
Loading section .text, size 0xfb58 lma 0x200
Loading section .rodata, size 0x18e8 lma 0xfd58
Loading section .data, size 0x990 lma 0x11640
Loading section .sdata, size 0x9c lma 0x11fd0
Start address 0x0, load size 73364
Transfer rate: 23 KB/sec, 4075 bytes/write.
Section reset, range 0x0 -- 0x10: matched.
Section eirq, range 0x100 -- 0x108: matched.
Section ovw, range 0x120 -- 0x124: matched.
Section undef, range 0x140 -- 0x144: matched.
Section sysc, range 0x160 -- 0x164: matched.
Section break, range 0x180 -- 0x184: matched.
Ignoring packet error, continuing...
upload.gdbinit:4: Error in sourced command file:
Reply contains invalid hex digit 105 

Debugausgabe meines GDB Servers:
(GDB ->) $X11640,990:@[...]#d8
(GDB <-) +
GDB command: X11640,990
(GDB <-) $OK#9a

(GDB ->) $X11fd0,9c: [...]#56
(GDB <-) +
GDB command: X11fd0,9c
(GDB <-) $OK#9a

(GDB ->) $P25=00000000#74
(GDB <-) +
GDB command: P25=00000000
(GDB <-) $OK#9a

(GDB ->) $m0,4#fd
(GDB <-) +
GDB command: m0,4
(GDB <-) $3c1d0050#f0

(GDB ->) $qCRC:0,10#40
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000000
len:  16
(GDB <-) $C4775b330#12

(GDB ->) $qCRC:100,8#78
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000100
len:  8
(GDB <-) $Cd3038f29#46

(GDB ->) $qCRC:120,4#76
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000120
len:  4
(GDB <-) $Ce61cbe87#a8

(GDB ->) $qCRC:140,4#78
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000140
len:  4
(GDB <-) $Ce61cbe87#a8

(GDB ->) $qCRC:160,4#7a
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000160
len:  4
(GDB <-) $Ce61cbe87#a8

(GDB ->) $qCRC:180,4#7c
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000180
len:  4
(GDB <-) $Ce61cbe87#a8

(GDB ->) $qCRC:200,fb58#76
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000200
len:  64344
(GDB <-) $C66964a55#1d

(GDB ->) $D#44
(GDB <-) +
GDB command: D
(GDB <-) $OK#9a

Warum auch immer der GDB wegen eines invaliden Zeichens 105 rummeckert 
(das wäre ein 'i').

von Martin S. (strubi)


Bewertung
0 lesenswert
nicht lesenswert
Moin,

den hier schon probiert?
set remotetimeout 99999

Wenn das auch nicht geht, liegt's an bloedem Timing, was insbes. bei 
seriellen GDB-backends auftreten kann. Leider ist das GDB-Protokoll 
ziemlich 'broken by design'. Nehme mal an, dass du nicht EJTAG 
implementiert hast..

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


Bewertung
0 lesenswert
nicht lesenswert
Das hab ich jetzt mal eingebaut, aber es ändert nichts.

Ich warte jetzt einfach noch 5sek zusätzlich bevor ich die Antwort 
schicke.
Das zeitliche Verhalten ist so:
(GDB ->) $qCRC:200,fb58#76
(GDB <-) +
GDB command: qCRC
gdb_demux_commands_q: CRC
addr: 0x00000200
len:  64344
---- Berechnungszeit + 5s ----
(GDB <-) $C66964a55#1d

---- GDB wirft die Fehlermeldung ---

(GDB ->) $D#44
(GDB <-) +
GDB command: D
(GDB <-) $OK#9a

Was nach den Klammern steht kommt über USB CDC rein oder wird darüber 
ausgesendet.
Das ohne Klammern ist Debugtext.

Komplett falsch kanns ja eigentlich nicht sein, sonst hätte der GDB 
schon bei den CRCs davor gemeckert?

Ich muss mal gucken ob ich den GDB dazu bringen kann mir anzuzeigen was 
er empfängt, dann könnt ich sehen ob da vllt doch ein 'i' irgendwie in 
den USB CDC TX Buffer reinfällt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.