Forum: Compiler & IDEs Welche GDB Kommandos gibt es?


von Florian (Gast)


Lesenswert?

Hallo

Ich würde gerne die im GDB verfügbaren Kommandos und deren Syntax 
wissen.
Eventuell kann damit dann das Wiki erweitert werden.
Ich habe einen mega32 und einen AVR Dragon welche per JTAG verbunden 
sind.
Auf Softwareseite wird avarice 2.7 und avr-gdb 6.7.1 unter Linux 
verwendet.

Mit google habe ich bereits folgende Kommandos in Erfahrung gebracht:

Ausführung starten/fortsetzen:
  continue

breakpoints setzen:
  break symbol
bzw
  break *adresse

watchpoints setzen:
  watch symbol
bzw
  watch *adresse

break/watchpoints anzeigen:
  info breakpoints

break/watchpoints löschen:
  delete breakpoints [x]

daten im stack betrachten
  info frame [x]
und
  backtrace



Mit diesen Kommandos kommt man bestimmt schon sehr weit.
Jedoch fehlt mir noch etwas.

Im Datenblatt zum mega32 wird unter "Using the On-chip Debug System" 
ein "Break Point with mask(“range Break Point”)" erwähnt.

Wenn ich den Sourcecode von avarice richtig interpretiere kann zu einem 
Watchpoint eine länge übergeben werden. Jedoch hab ich keine ahnung wie 
ich  das im gdb eingeben muss. Google und die hilfe des gdbs haben mir 
bisher leider keine Antwort geliefert.


Gruß

Florian

von Stefan B. (stefan) Benutzerseite


Lesenswert?


von Florian (Gast)


Lesenswert?

Danke für den tollen Link.
Das Pdf werd ich mir sofort ausdrucken.

Jedoch steht da nichts zum "range Break Point"
Oder ist das mit dem gdb nicht möglich?

Gruß

Florian

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


Lesenswert?

Florian wrote:

> Jedoch steht da nichts zum "range Break Point"
> Oder ist das mit dem gdb nicht möglich?

Der GDB nennt das einen watchpoint.  Der range breakpoint, den manche
ICEs beherrschen, ist eine sehr stark eingeschränkte Version eines
watchpoints, bei der man eine Basisadresse und eine Bitmaske angibt,
wobei die Basisadresse alle Maskenbits 0 hat.  Der Watchpoint des
GDB orientiert sich stärker an den Belangen der Hochsprache, indem die
Intention ist, dass man ihn auf eine bestimmte Variable ansetzt, die
man überwachen will (egal, wie groß sie ist).  Daraus entsteht natür-
lich das Dilemma, dass nicht alle möglichen Watchpoints in der
Hardware des ICE abgebildet werden können.  Die anderen kann der GDB
zwar trotzdem noch über eine Emulation benutzen, aber sowas will man
schon auf einem schnellen PC nicht wirklich haben, auf einem Controller
mit einem ICE dazu würde das Debuggen damit wahrscheinlich Wochen in
Anspruch nehmen.

Man kann aber GDB-typisch ja völlig beliebige Ausdrücke für den
Watchpoint angeben und auf diese Weise auch einen Datentyp der
entsprechenden Größe per typecast auf die gewünschte Adresse ansetzen.

von Rolf Magnus (Gast)


Lesenswert?

> Ich würde gerne die im GDB verfügbaren Kommandos und deren Syntax
> wissen.

Schon mal in GDB selbst "help" versucht?

von Florian (Gast)


Lesenswert?

@Rolf Magnus:
Entweder ist mein Englisch so verdammt schlecht, oder mit der Hilfe im 
gdb lässt sich meine Frage nicht beantworten.  ;-)

@Jörg Wunsch:
Danke das hat mir für das Verständnis der Funktionsweise sehr geholfen.
Jedoch weiß ich immernoch nicht wie ich das genau eingeben soll/kann.

Wie würde der Befehl aussehen, um einen "range watchpoint" auf 4 byte im 
Sram ab adresse 0x60 zu setzen?

  watch (*4*sizeof(char))0x800060

könnte das so klappen?
Kann das erst morgen testen, da die Hardware in der Firma ist.

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


Lesenswert?

watch *(uint32_t *)0x800060

würde ich mal aus dem Hut sagen.  Kann's auch gerade nicht testen.

von Florian (Gast)


Lesenswert?

Das scheint so nicht zu funktionieren.

Mit
1
 watch uart_tx_buffer
wird nur ein Software Watchpoint gesetzt der sehr sehr langsam ist.

Mit
1
 watch *uart_tx_buffer
bzw
1
 watch uart_tx_buffer[0]
kann ich einen Hardware watchpoint auf den buffer setzen. Jedoch 
reagiert er nur, wenn sich das 0. Element ändert.

Durch einsetzen von (uint32_t) oder (uint32_t*) ändert sich nur, wie gdb 
den Inhalt von uart_tx_buffer[0] darstellt.

Wenn uart_tx_buffer im Sram ab adresse 0x9e liegt dann sollte mit
1
 watch *0x80009e
doch das selbe Ergebnis herauskommen?

Das Klappt aber nicht. Laut debug output von avarice wird der watchpoint 
zwar gesetzt aber es passiert nichts und das Programm läuft.
Breche ich dann das Programm ab meckert gdb, dass der watchpüoint nicht 
entfernt werden konnte.

Hier die Ausgbabe von avarice.
1
...
2
GDB: <Z2,80009e,2>
3
BP ADD type: 3  addr: 0x80009e BP ADD type: 6  addr: 0xfffffffe Slot 0 full
4
Slot 0 full
5
range BP ADDED: 0x80009e/0xfffffffe
6
Slot 0 full
7
Slot 0 full
8
->GDB: OK
9
GDB: <vCont?>
10
->GDB:
11
GDB: <Hc0>
12
->GDB:
13
GDB: <c>
14
Slot 0 full
15
Slot 0 full
16
Breakpoint added in ICE. slot: 2  type: -2147483645  addr: 0xfffffffe
17
...
18
Breakpoint added in ICE. slot: 3  type: 6  addr: 0xfffffffe
19
...
20
->GDB: T0220:82;21:5508;22:9c000000;
21
GDB: <z2,80009e,2>
22
BP DEL type: 3  addr: 0x80009e FAILED
23
->GDB: E01
24
...

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


Lesenswert?

Florian wrote:

> Durch einsetzen von (uint32_t) oder (uint32_t*) ändert sich nur, wie
> gdb den Inhalt von uart_tx_buffer[0] darstellt.

watch *(uint32_t *)uart_tx_buffer

Wird aber nicht funktionieren, weil das ICE das nicht kann:

> Wenn uart_tx_buffer im Sram ab adresse 0x9e liegt dann sollte
> mit watch *0x80009e

0x9e kann man nämlich bestenfalls mit einer Maske von 0x01 (also als
uint16_t) zu einem range breakpoint erweitern, mehr geht nicht.  Das
ist das Dilemma der einfachen Implementierung im ICE als Offset +
Maske: der AVR selbst benötigt ja kein Alignment für seine Daten
(sodass der Compiler auch keins benutzt), aber die range breakpoints
benötigen Daten, die sauber ausgerichtet sind, sonst kann man sie
nicht benutzen, da die Objektgrenze über einen darstellbaren range
hinaus geht.

von Florian (Gast)


Lesenswert?

Hallo

Die Einschränkungen der range breakpoints auf seiten des Controllers 
sind mir  klar. Der breakpoint kann immer nur 2 hoch x byte anschauen 
wobei das x durch die Maske bestimmt wird.

Die Einschränkungen des avarice noch nicht ganz.
Durch einen Blick in die sourcen weiß ich:
range bp nur im sram
(address & mask) muss 0 sein

Ich verstehe aber immer noch nicht wie ich das in den gdb eingeben muss.
Laut avarice debug Ausgaben sind diese breakpoints identisch
1
watch *(uint32_t)0x80009c
2
watch *0x8009c
1
range BP ADDED: 0x80009c/0xfffffffe

bei uint32_t hätte ich aber 0xfffffffc als Maske erwartet

Gruß

Florian

PS:
in jtag2bp.cc scheint in Zeile 287 ein Tippfehler zu sein.
Oder soll da eine Zuweisung im if sein?

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


Lesenswert?

Florian wrote:

> Ich verstehe aber immer noch nicht wie ich das in den gdb eingeben muss.
> Laut avarice debug Ausgaben sind diese breakpoints identisch

> watch *(uint32_t)0x80009c

Ich meinte auch *(uint32_t *)0x80009c

Aber: jetzt sitze ich selbst vorm GDB, und er kann in der Tat
offenbar nicht mehr als 16 bits auf einmal in einen hardware
watchpoint nehmen.  Er fragt auch gar nicht erst das AVaRICE,
an diesem kann es also nicht liegen.  Nun habe ich mich mal durch
den GDB-Code gehangelt, und es sieht mir so aus, als hätte niemand
da je eine Anpassung für den AVR geschrieben.  Damit fällt das
Ganze letztlich zurück auf das hier (in target.c):
1
static int
2
default_region_size_ok_for_hw_watchpoint (int byte_count)
3
{
4
  return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr));
5
}

Damit ist klar, warum man nur 1- oder 2-Byte-Bereiche als
Hardware-Watchpoint aktiviert bekommt. :-/  Da außerdem das
default-Scenario nur die Länge, nicht aber die Adresse des
watchpoints betrachtet, genügt das für den AVR und das JTAG ICE
ohnehin nicht.  Es gibt aber einen Makro
TARGET_REGION_OK_FOR_HW_WATCHPOINT, den man offensichtlich
irgendwie unter gdb/config/avr/nm-avr(?).h setzen kann um
anzuzeigen, was man tatsächlich als hardware watchpoint
unterstützen kann.  Das könnte man sich ja mal ansehen...

> in jtag2bp.cc scheint in Zeile 287 ein Tippfehler zu sein.
> Oder soll da eine Zuweisung im if sein?

Wo du Recht hast, hast du Recht.  OK, danke sehr, ist repariert.

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.