Was bedeutet 0x0800f298 in ?? () bedeuten?

Ich verwende GDB, um ein Programm für einen Cortex M3 zu debuggen. In den Funktionen, bei denen das Programm abstürzt, wenn ich Zeile für Zeile ausführe (mit n), erhalte ich schließlich:

(gdb) n 
0x0800f498 in ?? ()

jetzt, wenn ich zurückverfolge (mit bt) direkt nachdem ich bekomme:

(gdb) bt
#0  0x0800f498 in ?? ()
#1  0xfffffff8 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Worauf genau beziehen sich die Adressen 0x0800f498und 0xfffffff8? Wie bin ich dort angekommen? Würde ein Blick auf die Linker- mapDatei helfen?

Bearbeiten : Wenn ich info registersdas mache, bekomme ich:

info registers
r0             0x2001ffe8       537001960
r1             0x0      0
r2             0x0      0
r3             0x7ada53e6       2061128678
r4             0x0      0
r5             0x0      0
r6             0x0      0
r7             0x0      0
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
sp             0x2001ffb0       0x2001ffb0
lr             0xfffffff9       4294967289
pc             0x800f499        0x800f499
fps            0x0      0
cpsr           0x1000023        16777251
das ist nur die Rücksprungadresse, da sie auf dem Stapel steht und ein hilfloser Debugger nicht weiß, worauf sie sich bezieht. wie sollen wir das wissen? sieht aber 0xfffffff8komisch aus, vielleicht die Vermutung "korrupter Stack?" ist richtig.
Sie müssen wirklich die Cortex M3-Spezifikationen in ARM ARM für ARMv7-M lesen. LR = 0xFFFFFFF9ist ein "magischer" Wert für die Ausnahmerückgabe.
@TurboJ Sie sollten dies zu einer Antwort machen, damit ich darüber abstimmen kann

Antworten (2)

Sie haben zwei Probleme:

  1. Ihr Debugger kennt keine ARMv7-M-Ausnahmen.
  2. Ihr Code löst wahrscheinlich aufgrund eines Programmierfehlers einen Fehler aus, z. B. wenn Sie vergessen haben, eine Peripherieuhr zu aktivieren.

In diesem Fall wird der Debugger durch den magischen 0xFFFFFFFx-Wert in LR verwirrt. Sie könnten versuchen, die auf dem Stack gespeicherten Registerwerte manuell zu überprüfen, um den ursprünglichen PC-Wert zu finden.

Die Adresse 0x0800f498befindet sich möglicherweise im Hard FaultAusnahmehandler. Normalerweise verwende ich meinen eigenen Handler mit einer speziellen LED-Blinksequenz, damit ich weiß, wenn etwas schief gelaufen ist.

Die gdb in Sourcery CodeBench unterstützt dieses Ausnahmemodell, aber Sie benötigen möglicherweise eine target.xmlDatei, um es zu aktivieren.

Die Hexadezimalzahl ist der Wert des Programmzählers oder der Stapeladresse (sehen Sie in Ihren Handbüchern nach), das "??" ist die Funktion, die gerade ausgeführt wird.

Wenn Sie Ihren Code mit Debugging-Symbolen kompilieren (mit gcc müssen Sie das -gFlag verwenden), sollte der Debugger in der Lage sein, den Funktionsnamen korrekt auszugeben.

Um es selbst herauszufinden, können Sie entweder die Map-Datei studieren oder verwenden, address2linedie sich in Ihrer GNU ARM-Toolchain befinden sollte.

Ich debugge mit dem -gFlag. Normalerweise gibt es den Namen der Funktion ganz schön aus, aber hier - wo mein Programm abstürzt - wird es verwirrt.
Dann hat Ihr Programm wahrscheinlich den Stapelrahmen zerstört, was bedeutet, dass Sie ihn nicht debuggen können. Versuchen Sie, die Anweisung abzufangen, bevor sie fehlschlägt, indem Sie sie einzeln durchgehen. Verwenden Sie Breakpoints, um den Suchraum einzuschränken.