2012-03-23 1 views
20

Je débogue ce logiciel pour un système embarqué STM32. Dans l'une des fonctions mes programmes arrète pas de taper une sorte de point d'arrêt:SIGTRAP malgré aucun point d'arrêt défini; point d'arrêt matériel caché?

SIGTRAP, Trace/piège breakpoint

Cependant, GDB, quand je fais info breakpoints je reçois No breakpoints or watchpoints. Le point d'arrêt correspond en fait à un point d'arrêt que j'avais défini il y a un certain temps, dans une autre version de l'exécutable. Lorsque j'ai défini ce point d'arrêt, GDB m'a dit automatically using a hardware breakpoint on read-only memory (ou un message similaire).

Je pense que le point de rupture matériel reste sur ma puce, malgré le chargement d'une nouvelle version du logiciel. S'il y a effectivement un point d'arrêt parasite, comment puis-je le localiser et l'enlever?

+0

Réinitialiser la CPU. :) (les points d'arrêt hw peuvent être laissés installés, si gdb meurt ou s'il ne supprime pas tous les points d'arrêt existants à la sortie/reconnexion). – dbrank0

+0

Notez que les registres de débogage peuvent persister dans certains types de réinitialisations. Une réinitialisation à la mise sous tension complète l'effacera définitivement. – TJD

+1

Qu'entendez-vous par "réinitialisation à pleine puissance"? J'ai essayé de débrancher/rebrancher, mais le point d'arrêt persiste. – Randomblue

Répondre

18

Ok. Réponse longue: Les points d'arrêt matériels sont généralement définis en écrivant dans certains registres de CPU spéciaux. Ceci est fait par gdb. Si gdb meurt, il peut laisser ceux installés dans le CPU. Je suppose que votre implémentation (de gdb) ne les efface pas ou ne les examine pas, quand elle se connecte à votre cible. Pour les localiser, vous devez répertorier le contenu des registres de points d'arrêt matériels sur votre CPU (vous ne savez pas comment le faire sur STM32). Contournement serait (informé devinez) être ceci: placer peu de points d'arrêt matériels (typiquement il y a seulement peu, rarement plus de 8) en utilisant gdb, puis les enlever tous. Cela devrait remplacer, puis nettoyer ces registres hw. Une fois que vous avez défini ces points d'arrêt (avant de les supprimer), faites "continuer" (juste au cas où, gdb n'établit des points d'arrêt qu'à ce moment-là).

+1

Merci pour l'idée de définir de nombreux points d'arrêt, puis en les supprimant. Cela devrait résoudre le problème. Un peu ennuyeux que gdb n'efface pas ces points d'arrêt quand il se connecte à ma cible. – Randomblue

1

Le code que vous utilisez peut contenir

int $0x03 ; talking about x86, don't know STM32 mnemo 

qui invoque un SIGTRAP. SIGTRAP doit être une instruction de point d'arrêt en cours d'exécution.

2

Déboguez ceci en inspectant votre pointeur d'instruction, il est probablement indiqué à une adresse qui contient l'instruction BKPT (vous devrez rechercher quel est le code réel). De là, vous devrez travailler en arrière en fonction de la pile et du pointeur d'instruction et voir si vous êtes là où vous vous attendez. Il pourrait y avoir un certain nombre de choses à l'origine de ceci, de GDB insérant une instruction de point d'arrêt qu'il a échoué à effacer, à la corruption de la mémoire.

2

Ce qui suit m'a aidé:

# Ones I hit the SIGTRAP: 
(gdb) f 0 # Show the current stack frame of the current thread. 
#0 0x4003ed70 in [email protected]@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. 
+1

C'est la même idée que la réponse acceptée, mais il est bon de noter que la commande hbreak est la clé. La commande de rupture normale définit les points d'arrêt logiciels au lieu d'écraser les points d'arrêt précédents –

0

Si ajout et la suppression des points d'arrêt du matériel ne fonctionne pas, vérifier le vecteur d'interruption.

Sur les microcontrôleurs Cortex-M, toutes les entrées de gestionnaire doivent avoir une adresse impaire (ARM Cortex-M FAQ). Si ce n'est pas le cas, un message UsageFault de type INVSTATE est déclenché et le MCU est arrêté. GDB interprète cela comme un SIGABRT.

Si l'une des entrées a une adresse même, vérifiez si la fonction de gestionnaire a les .thumb_func et .type directives (NXP Avoid hardfault, HardFault and .thumb_func).

Exemple pour un HardFault_Handler:

.thumb_func 
.type HardFault_Handler, %function 
HardFault_Handler: 
    TST LR, #4 
    ITE EQ 
    MRSEQ R0, MSP 
    MRSNE R0, PSP 
    B hard_fault_handler_c 
Questions connexes