2012-02-02 23 views
5

Desidero, come dice il titolo, stampare il contenuto della pila nel mio programma C.Come posso stampare il contenuto dello stack nel programma C?

Questi sono i passi che ho preso:

  • Ho fatto un file di semplice assemblaggio (helper.s) che includeva una funzione per restituire l'indirizzo del mio registro EBP e una funzione per restituire l'indirizzo del mio esp registrare

    .globl get_esp 
    
    get_esp: 
        movl %esp, %eax 
        ret 
    # get_ebp is defined similarly, and included in the .globl section 
    
  • ho chiamato il get_esp() e get_ebp() funzioni dal mio programma C (fpC = get_esp(); dove FPC è un int)
  • i (con successo, credo) di stampa editore l'indirizzo dei miei registri esp e ebp (fprintf (stderr, "%x", fcP);)
  • Ho provato, e ho fallito, a stampare il contenuto del mio registro esp. (Ho provato fprintf (sderr, "%d", *fcP); e fprintf (sderr, "%x", *((int *)fcP));, tra gli altri metodi). Il mio programma raggiunge un errore di segmentazione in fase di esecuzione quando questa riga viene elaborata.

Cosa sto sbagliando?

MODIFICA: È necessario eseguire questa operazione richiamando queste funzioni di assieme per ottenere i puntatori dello stack. EDIT2: questo è un compito a casa.

+0

Cosa intendi quando dici di aver fallito? Che risultato hai ottenuto e cosa ti aspettavi? –

+0

Per stampare i puntatori, è necessario usare 'printf ("% p ", (void *) (p))'. Il "contenuto di% esp" è un puntatore. –

+0

@CarlNorum: No, l'uso di 'printf' è semplicemente richiesto dallo standard C. (Cfr. "Argomenti variadici".) –

risposta

5

Se si utilizza un sistema GNU, è possibile utilizzare l'estensione di GNU nella libreria C per trattare i backtrace, vedere here.

#include <execinfo.h> 

int main(void) 
{ 
    //call-a-lot-of-functions 
} 

void someReallyDeepFunction(void) 
{ 
    int count; 
    void *stack[50]; // can hold 50, adjust appropriately 
    char **symbols; 

    count = backtrace(stack, 50); 
    symbols = backtrace_symbols(stack, count); 

    for (int i = 0; i < count; i++) 
     puts(symbols[i]); 

    free(symbols); 
} 
+0

Questo sembra un buon modo per farlo, ma ho bisogno di implementarlo utilizzando le funzioni di assemblaggio (per i requisiti di assegnazione). Avrei dovuto specificarlo nel mio problema in origine. – Nate

+0

È importante contrassegnare le domande a casa come compiti a casa. – dreamlax

+0

Mi dispiace per quello. Post originale modificato – Nate

4

get_esp rendimenti esp in quanto è all'interno della funzione. Ma questo non è lo stesso di esp nella funzione di chiamata, perché l'operazione di chiamata cambia esp.

Si consiglia di sostituire la funzione con un pezzo di gruppo in linea. In questo modo esp non cambierà mentre provi a leggerlo.

Inoltre, la stampa su sderr non sarebbe di aiuto. Dalla mia esperienza, stderr funziona molto meglio.

Problemi correlati