2012-03-23 10 views
20

Sto eseguendo il debug di questo software per un sistema embedded STM32. In una delle funzioni miei programmi continua a colpire una sorta di punto di interruzione:SIGTRAP nonostante non siano stati impostati punti di interruzione; punto di rottura hardware nascosto?

SIGTRAP, Trace/breakpoint trappola

Tuttavia, in GDB, quando faccio info breakpoints ricevo No breakpoints or watchpoints. Il punto di interruzione corrisponde in realtà a un punto di interruzione che avevo impostato molto tempo fa, in un'altra versione dell'eseguibile. Quando ho impostato quel punto di interruzione, GDB mi ha detto automatically using a hardware breakpoint on read-only memory (o un messaggio simile).

Penso che il punto di interruzione hardware rimanga sul mio chip, nonostante abbia caricato una nuova versione del software. Se esiste effettivamente un punto di interruzione spuria, come posso individuarlo e rimuoverlo?

+0

resettare la CPU. :) (i punti di interruzione hw possono essere lasciati installati, se gdb muore o se non cancella tutti i breakpoint esistenti in uscita/riconnessione). – dbrank0

+0

Si noti che i registri di debug possono persistere tra alcuni tipi di reimpostazione. Tuttavia, un reset completo all'accensione lo cancellerà definitivamente. – TJD

+1

Cosa intendi per "reset completo all'accensione"? Ho provato a scollegare/ricollegare, ma il punto di interruzione persiste. – Randomblue

risposta

18

Ok. Risposta lunga: I breakpoint hardware vengono solitamente impostati scrivendo su alcuni registri CPU speciali. Questo è fatto da gdb. Se gdb muore, può lasciare quelli installati nella CPU. Immagino che la tua implementazione (di gdb) non la cancelli o la esamini quando si connette al tuo target. Per individuarli, è necessario elencare il contenuto dei registri dei breakpoint hardware sulla CPU (non so come farlo su STM32). La soluzione sarebbe (ipotesi informata) essere questa: impostare pochi breakpoint HW (in genere ce ne sono solo pochi, raramente più di 8) utilizzando gdb, quindi rimuoverli tutti. Questo dovrebbe sovrascrivere e quindi pulire quei registri hw. Una volta impostati questi punti di interruzione (prima di rimuoverli), fare "continua" (nel caso in cui gdb imposta breakpoint solo in quel momento).

+1

Grazie per l'idea di impostare molti punti di interruzione e quindi rimuoverli. Questo dovrebbe risolvere il problema. Un po 'fastidioso che gdb non cancelli quei breakpoint quando si collega al mio target. – Randomblue

1

Il codice si esegue può contenere

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

che invoca un SIGTRAP.

2

SIGTRAP deve essere un'istruzione di punto di interruzione in esecuzione.

Esegui il debug esaminando il puntatore delle istruzioni, è probabile che sia puntato su un indirizzo che contiene l'istruzione BKPT (dovrai cercare qual è il codice reale).

Da lì si dovrà lavorare a ritroso sulla base della stack pointer e l'istruzione e vedere se sei dove ci si aspetta di essere. Potrebbero esserci un numero di cose che causano questo, da GDB che inserisce un'istruzione breakpoint che non è riuscita a cancellare, alla corruzione della memoria.

2

Di seguito mi ha aiutato:

# 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

Questa è la stessa idea della risposta accettata, ma è bene notare che il comando hbreak è la chiave. Il comando di interruzione normale imposta i punti di interruzione del software anziché sovrascrivere i breakpoint precedenti –

0

Se aggiunta e la rimozione dei punti di interruzione hardware non aiuta, controllare il vettore di interrupt.

On Cortex-M microcontrollori tutte le voci del gestore dovrebbe avere un indirizzo dispari (ARM Cortex-M FAQ). In caso contrario, viene attivato un UsageFault di tipo INVSTATE e l'MCU viene arrestato. GDB lo interpreta come SIGABRT.

Se una delle voci ha un ancora l'indirizzo, quindi verificare se la funzione di gestione ha le .thumb_func e .type direttive (NXP Avoid hardfault, HardFault and .thumb_func).

Esempio per 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 
Problemi correlati