SIGTRAP en dépit de l'absence de points de rupture définis; point de rupture matériel caché?

je suis en train de déboguer ce logiciel pour un système embarqué STM32. Dans l'une des fonctions mes programmes continuent à frapper une sorte de point de rupture:

SIGTRAP, Trace / breakpoint trap

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

je pense que le point de rupture matériel reste sur ma puce, malgré avoir chargé une nouvelle version du logiciel. S'il y a bien un faux point de rupture, Comment puis-je le localiser et le supprimer?

23
demandé sur Randomblue 2012-03-23 14:26:37

5 réponses

Ok. Réponse longue: Les points de rupture du matériel sont généralement définis en écrivant à certains registres CPU Spéciaux. Ceci est fait par gdb. Si gdb meurt, il peut laisser ceux installés dans CPU. Je suppose que votre implémentation (de gdb) ne les clarifie pas ou ne les examine pas, quand elle se connecte à votre cible. Pour les localiser, vous devez lister le contenu des registres des points de rupture du matériel sur votre CPU (ne sait pas comment le faire sur STM32). La solution serait (deviné informé) être ceci: fixer quelques points de rupture HW (en général, il n'y en a que quelques-uns, rarement plus de 8) en utilisant gdb, puis supprimez-les tous. Cela devrait écraser et ensuite 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ù, puisque gdb ne définit les points d'arrêt qu'à ce moment-là).

20
répondu dbrank0 2012-03-23 15:10:50

La suite m'a aidé:

# 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.
3
répondu Robin Kuzmin 2017-06-22 19:06:23

SIGTRAP devrait être une instruction de point de rupture qui est exécutée.

déboguez ceci en inspectant votre pointeur d'instruction, il est très probablement pointé vers une adresse qui contient l'instruction BKPT (vous devrez chercher ce qu'est le code réel).

A partir de là, vous devrez travailler à l'envers en fonction de la pile et du pointeur d'instruction et voir si vous êtes là où vous vous attendez à être. Il pourrait y avoir un certain nombre de causes à cela, à partir de GDB insérant une instruction breakpoint qu'il n'a pas réussi à effacer, à se souvenir de la corruption.

2
répondu dragonx 2012-03-29 15:29:15

le code que vous utilisez peut contenir

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

qui invoque un SIGTRAP.

1
répondu iehrlich 2012-03-28 14:57:07

si ajouter et supprimer des points de rupture matériels n'aide pas, vérifiez le vecteur d'interruption.

sur les microcontrôleurs Cortex-M toutes les entrées du gestionnaire doivent avoir une adresse impaire (ARM Cortex-M FAQ). S'ils ne le font pas, alors une erreur D'UsageFault de type INVSTATE est déclenchée et le MCU est arrêté. GDB interprète cela comme un SIGABRT.

Si l'une des entrées a une même adresse, puis vérifiez si la fonction de gestionnaire a l' .thumb_func et .type directives ( NXP Avoid hardfault, HardFault et .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
1
répondu Sussch 2017-10-19 07:53:41