2012-03-23 20 views
20

Estoy depurando esta pieza de software para un sistema integrado STM32. En una de las funciones de mis programas que se mantenga golpear una especie de punto de interrupción:SIGTRAP a pesar de no establecer puntos de interrupción; punto de corte de hardware oculto?

SIGTRAP, Trace/trampa de punto de interrupción

Sin embargo, en el BGF, cuando lo haga info breakpoints consigo No breakpoints or watchpoints. El punto de interrupción en realidad corresponde a un punto de interrupción que había establecido hace bastante tiempo, en otra versión del ejecutable. Cuando establecí ese punto de interrupción, GDB me dijo automatically using a hardware breakpoint on read-only memory (o un mensaje similar).

Creo que el punto de interrupción del hardware permanece en mi chip, a pesar de haber cargado una nueva versión del software. Si hay un punto de ruptura espurio, ¿cómo puedo localizarlo y eliminarlo?

+0

Reiniciar la CPU. :) (hw puntos de interrupción se pueden dejar instalados, si gdb muere o si no elimina todos los puntos de interrupción existentes en la salida/reconexión). – dbrank0

+0

Tenga en cuenta que los registros de depuración pueden persistir en algunos tipos de reinicios. Sin embargo, un reinicio completo de encendido definitivamente lo borrará. – TJD

+1

¿Qué quiere decir con "reinicio de encendido completo"? Intenté desenchufar/volver a conectar, pero el punto de interrupción persiste. – Randomblue

Respuesta

18

Ok. Respuesta larga: Los puntos de interrupción del hardware generalmente se configuran escribiendo en algunos registros de CPU especiales. Esto es hecho por gdb. Si gdb muere, puede dejar los instalados en la CPU. Supongo que su implementación (de gdb) no borra ni examina esos, cuando se conecta a su objetivo. Para localizarlos, necesitaría enumerar los contenidos de los registros de punto de interrupción de hardware en su CPU (no sé cómo hacer esto en STM32). La solución sería (conjetura informada) ser esto: establecer algunos puntos de interrupción HW (por lo general, son pocos, rara vez más de 8) usando gdb, luego eliminarlos todos. Esto debería sobrescribir y luego limpiar esos registros de hw. Una vez que establezca esos puntos de interrupción (antes de eliminarlos), haga "continuar" (por si acaso, ya que gdb establece puntos de interrupción solo en ese momento).

+1

Gracias por la idea de establecer muchos puntos de interrupción, y luego eliminarlos. Eso debería resolver el problema. Un poco molesto que gdb no borre esos puntos de interrupción cuando se conecta a mi objetivo. – Randomblue

1

El código está ejecutando puede contener

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

que invoca una SIGTRAP.

2

SIGTRAP debe ser una instrucción de punto de interrupción que se está ejecutando.

Depure esto inspeccionando su puntero de instrucción, lo más probable es que apunte a una dirección que contiene la instrucción BKPT (tendrá que buscar cuál es el código real).

A partir de ahí, tendrá que trabajar hacia atrás según la pila y el puntero de instrucción y ver si está donde espera estar. Podría haber un número de cosas que causan esto, desde que GDB inserta una instrucción de punto de interrupción que no se borró, hasta daños en la memoria.

2

El siguiente me ayudó:

# 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

Esta es la misma idea que la respuesta aceptada, pero es bueno tener en cuenta que el comando hbreak es la clave. El comando de interrupción normal configurará los puntos de interrupción del software en lugar de sobrescribir los puntos de interrupción anteriores –

0

Si adición y eliminación de puntos de interrupción de hardware no funciona, compruebe el vector de interrupción.

En los microcontroladores Cortex-M todas las entradas del controlador deben tener una dirección impar (ARM Cortex-M FAQ). Si no lo hacen, se desencadena un UsageFault de tipo INVSTATE y se detiene la MCU. GDB interpreta esto como un SIGABRT.

Si una de las entradas tiene una dirección, incluso, a continuación, comprobar si la función de controlador tiene las .thumb_func y .type directivas (NXP Avoid hardfault, HardFault and .thumb_func).

Ejemplo para 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 
Cuestiones relacionadas