Ich debugge diese Software für ein eingebettetes STM32-System. In einer der Funktionen treffen meine Programme immer wieder auf eine Art Haltepunkt:
SIGTRAP, Ablaufverfolgungs-/Haltepunktfalle
Allerdings in GDB, wenn ich das tue info breakpoints Ich bekomme No breakpoints or watchpoints. Der Haltepunkt entspricht tatsächlich einem Haltepunkt, den ich vor einiger Zeit in einer anderen Version der ausführbaren Datei gesetzt hatte. Als ich diesen Breakpoint gesetzt habe, hat GDB es mir gesagt automatically using a hardware breakpoint on read-only memory (oder eine ähnliche Meldung).
Ich denke, der Hardware-Haltepunkt bleibt auf meinem Chip, obwohl ich eine neue Version der Software geladen habe. Wenn es tatsächlich einen falschen Haltepunkt gibt, wie kann ich ihn finden und entfernen?
Setzen Sie die CPU zurück. 🙂 (hw Breakpoints können installiert bleiben, wenn gdb stirbt oder wenn es nicht alle bestehenden Breakpoints beim Beenden/Wiederverbinden löscht).
– dbrank0
23. März 2012 um 15:03 Uhr
Beachten Sie, dass Debug-Register bei einigen Arten von Zurücksetzungen bestehen bleiben können. Ein vollständiger Power-On-Reset wird es jedoch definitiv löschen.
– TJD
23. März 2012 um 21:37 Uhr
Was meinst du mit “vollständiger Power-On-Reset”? Ich habe versucht, das Gerät aus-/einzustecken, aber der Haltepunkt bleibt bestehen.
– Zufallsblau
24. März 2012 um 13:06 Uhr
Also, wenn ich das verstehe, haben Sie Ihr eingebettetes System aus- und eingeschaltet (und es gibt keine Backup-Batterie), die Stromversorgung Ihrer jtag-Schnittstelle / ICE ausgeschaltet und der Haltepunkt wird immer noch erreicht?
– dbrank0
27. März 2012 um 8:55 Uhr
@dbrank0: Ja. Nun, zumindest sagt mir GDB, dass ich einen SIGTRAP habe, den ich als Haltepunkt interpretiere.
– Zufallsblau
27. März 2012 um 9:35 Uhr
OK. Lange Antwort: Hardware-Haltepunkte werden normalerweise durch Schreiben in einige spezielle CPU-Register gesetzt. Dies wird von gdb erledigt. Wenn gdb stirbt, kann es die in der CPU installierten belassen. Ich denke, Ihre Implementierung (von gdb) löscht oder untersucht diese nicht, wenn sie sich mit Ihrem Ziel verbindet. Um sie zu finden, müssten Sie den Inhalt der Hardware-Haltepunktregister auf Ihrer CPU auflisten (weiß nicht, wie das auf STM32 geht). Die Problemumgehung wäre (informierte Vermutung): Setzen Sie einige HW-Haltepunkte (normalerweise gibt es nur wenige, selten mehr als 8) mit gdb und entfernen Sie sie dann alle. Dies sollte diese HW-Register überschreiben und dann bereinigen. Sobald Sie diese Haltepunkte gesetzt haben (bevor Sie sie entfernen), machen Sie “weiter” (nur für den Fall, da gdb nur zu diesem Zeitpunkt Haltepunkte setzt).
Vielen Dank für die Idee, viele Haltepunkte zu setzen und sie dann zu entfernen. Das sollte das Problem lösen. Ein bisschen ärgerlich, dass gdb diese Haltepunkte nicht löscht, wenn es sich mit meinem Ziel verbindet.
– Zufallsblau
23. März 2012 um 16:19 Uhr
Folgendes hat mir geholfen:
# Ones I hit the SIGTRAP:
(gdb) f 0 # Show the current stack frame of the current thread.
#0 0x4003ed70 in pthread_create@@GLIBC_2.4 () from /opt/CodeSourcery/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libpthread.so.0
# The fragment of interest is the current address: 0x4003ed70.
# Set the hardware assisted breakpoint at the current address:
(gdb) hbreak *0x4003ed70
# Continue execution (without hitting SIGTRAP):
(gdb) c
# Continuing.
Dies ist die gleiche Idee wie die akzeptierte Antwort, aber es ist gut zu beachten, dass der Befehl hbreak der Schlüssel ist. Der normale Break-Befehl setzt Software-Breakpoints, anstatt vorherige Breakpoints zu überschreiben
– Samuel Petrus
27. Juni 2017 um 12:33 Uhr
SIGTRAP sollte eine Breakpoint-Anweisung sein, die ausgeführt wird.
Debuggen Sie dies, indem Sie Ihren Anweisungszeiger untersuchen. Er zeigt höchstwahrscheinlich auf eine Adresse, die die BKPT-Anweisung enthält (Sie müssen nachschlagen, was der tatsächliche Code ist).
Von dort aus müssen Sie basierend auf dem Stapel und dem Anweisungszeiger rückwärts arbeiten und sehen, ob Sie dort sind, wo Sie es erwarten. Dies kann eine Reihe von Ursachen haben, von GDB, das eine Breakpoint-Anweisung einfügt, die nicht gelöscht werden konnte, bis hin zu Speicherbeschädigungen.
Wenn das Hinzufügen und Entfernen von Hardware-Haltepunkten nicht hilft, überprüfen Sie den Interrupt-Vektor.
Auf Cortex-M-Mikrocontrollern sollten alle Handler-Einträge eine ungerade Adresse haben (Häufig gestellte Fragen zu ARM Cortex-M). Wenn dies nicht der Fall ist, wird ein UsageFault des Typs INVSTATE ausgelöst und die MCU angehalten. GDB interpretiert dies als SIGABRT.
Setzen Sie die CPU zurück. 🙂 (hw Breakpoints können installiert bleiben, wenn gdb stirbt oder wenn es nicht alle bestehenden Breakpoints beim Beenden/Wiederverbinden löscht).
– dbrank0
23. März 2012 um 15:03 Uhr
Beachten Sie, dass Debug-Register bei einigen Arten von Zurücksetzungen bestehen bleiben können. Ein vollständiger Power-On-Reset wird es jedoch definitiv löschen.
– TJD
23. März 2012 um 21:37 Uhr
Was meinst du mit “vollständiger Power-On-Reset”? Ich habe versucht, das Gerät aus-/einzustecken, aber der Haltepunkt bleibt bestehen.
– Zufallsblau
24. März 2012 um 13:06 Uhr
Also, wenn ich das verstehe, haben Sie Ihr eingebettetes System aus- und eingeschaltet (und es gibt keine Backup-Batterie), die Stromversorgung Ihrer jtag-Schnittstelle / ICE ausgeschaltet und der Haltepunkt wird immer noch erreicht?
– dbrank0
27. März 2012 um 8:55 Uhr
@dbrank0: Ja. Nun, zumindest sagt mir GDB, dass ich einen SIGTRAP habe, den ich als Haltepunkt interpretiere.
– Zufallsblau
27. März 2012 um 9:35 Uhr