2012-02-02 18 views
5

Quiero, como dice el título, imprimir el contenido de la pila en mi programa C.¿Cómo puedo imprimir el contenido de la pila en el programa C?

Estos son los pasos que di:

  • hice un archivo de ensamblaje sencillo (helper.s) que incluye una función para devolver la dirección de mi registro ebp y una función para devolver la dirección de mi registro ESP

    .globl get_esp 
    
    get_esp: 
        movl %esp, %eax 
        ret 
    # get_ebp is defined similarly, and included in the .globl section 
    
  • me llamó el get_esp() y get_ebp() funciones de mi programa en C (fpC = get_esp(); donde FPC es un int)
  • I (con éxito, creo) de impresión ed la dirección de mis registros esp y ebp (fprintf (stderr, "%x", fcP);)
  • Intenté, y no pude, imprimir los contenidos de mi registro esp. (Intenté fprintf (sderr, "%d", *fcP); y fprintf (sderr, "%x", *((int *)fcP));, entre otros métodos). Mi programa alcanza un error de segmentación en el tiempo de ejecución cuando se procesa esta línea.

¿Qué estoy haciendo mal?

EDITAR: Esto se debe realizar llamando a estas funciones de ensamblaje para obtener los punteros de pila. EDIT2: Esta es una tarea de tarea.

+0

¿A qué te refieres cuando dices que falló? ¿Qué producción obtuviste y qué esperabas? –

+0

Para imprimir punteros, debe usar 'printf ("% p ", (void *) (p))'. El "contenido de% esp" es un puntero. –

+0

@CarlNorum: No, el uso de 'printf' es simplemente obligatorio según el estándar C. (Cf. "argumentos variados"). –

Respuesta

5

Si está utilizando un sistema GNU, puede usar la extensión de GNU a la biblioteca C para tratar trazas inversas, consulte 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

Parece una buena forma de hacerlo, pero tengo que implementar esto usando las funciones de ensamblaje (según los requisitos de asignación). Debería haber especificado eso en mi problema originalmente. – Nate

+0

Es importante que marque las tareas como tarea. – dreamlax

+0

Perdón por eso. Publicación original editada. – Nate

4

get_esp vuelve esp ya que está dentro de la función. Pero esto no es lo mismo que esp en la función de llamada, porque la operación de llamada cambia esp.

Recomiendo reemplazar la función con una pieza de montaje en línea. De esta forma, esp no cambiará cuando intente leerlo.

Además, imprimir en sderr no ayudaría. Desde mi experiencia, stderr funciona mucho mejor.

Cuestiones relacionadas