2012-03-04 10 views
11

Mi pregunta está relacionada con este SO post y algunos otros alike. Quería saber el nombre de la función de llamada, ya que en el momento de la falla de la aserción, no sé qué función pasó un valor de basura al destinatario. Un método es verificar todas las funciones que podrían llamar a esta función, pero eso es muy engorroso.Como saber la función que llama al trazar error de aserción

¿Puede sugerir una mejor solución, aunque dependiente de la plataforma? Estoy usando g ++ 4.6. Gracias por adelantado.

+1

no puedes ejecutar el programa en un depurador para ver el seguimiento de pila? – sth

+3

hay muchos casos de uso en los que no puede hacer esto – Coren

Respuesta

2

Ver backtrace().

p. Ej.

#include <execinfo.h> 
#include <stdio.h> 

void bar() { 
    void* callstack[128]; 
    int i, frames = backtrace(callstack, 128); 
    char** strs = backtrace_symbols(callstack, frames); 
    for (i = 0; i < frames; ++i) { 
    printf("%s\n", strs[i]); 
    } 
    free(strs); 
} 

int foo() { 
    bar(); 
    return 0; 
} 

int main() { 
    foo(); 
    return 0; 
} 

Salida:

0 a.out        0x0000000100000e24 bar + 28 
1 a.out        0x0000000100000e81 foo + 14 
2 a.out        0x0000000100000e96 main + 14 
3 a.out        0x0000000100000e00 start + 52 
4 ???         0x0000000000000001 0x0 + 1 

Ver:

How to generate a stacktrace when my gcc C++ app crashes

4

Usted tiene backtrace funciones en glibc. Puede permitirle tener trazas completas, con la función o el método de la persona que llama.

Si sólo desea la persona que llama, también hay specific functions en gcc sólo para esto:

__builtin_frame_address(int level); 

Con level == 1 que tiene la función de llamada. Vea this post para más detalles sobre cómo usarlo.

Aquí es el programa de ejemplo que se encuentra en la documentación:

#include <execinfo.h> 
#include <stdio.h> 
#include <stdlib.h> 

/* Obtain a backtrace and print it to stdout. */ 
void 
print_trace (void) 
{ 
    void *array[10]; 
    size_t size; 
    char **strings; 
    size_t i; 

    size = backtrace (array, 10); 
    strings = backtrace_symbols (array, size); 

    printf ("Obtained %zd stack frames.\n", size); 

    for (i = 0; i < size; i++) 
    printf ("%s\n", strings[i]); 

    free (strings); 
} 

/* A dummy function to make the backtrace more interesting. */ 
void 
dummy_function (void) 
{ 
    print_trace(); 
} 

int 
main (void) 
{ 
    dummy_function(); 
    return 0; 
} 
+0

También me parece conveniente emitir los resultados de 'backtrace' (los punteros sin formato). A continuación, puede utilizar la utilidad de línea de comandos 'addr2line' para convertirlo en nombres de archivo de origen reales y números de línea. –

+0

Muchas gracias. Pero, ¿cómo obtener el nombre de la función? Esto solo parece imprimir algunas direcciones. Perdonen mi ignorancia – user984260

+0

En cadenas [i], tiene nombre de funciones y con dlinfo del otro enlace, incluso puede mostrarle más información – Coren

Cuestiones relacionadas