2012-03-04 12 views
11

La mia domanda è correlata a questo SO post e ad altri alike. Volevo sapere il nome della funzione del chiamante, dal momento che al momento dell'errore di asserzione, non so quale funzione abbia passato a un valore di garbage to callee. Un metodo consiste nel controllare tutte le funzioni che potrebbero chiamare questa funzione, ma ciò è molto complicato.Come sapere la funzione del chiamante quando si registra l'errore dell'asserzione

Potete suggerire una soluzione migliore, anche se dipendente dalla piattaforma? Sto usando g ++ 4.6. Grazie in anticipo.

+1

non puoi semplicemente eseguire il programma in un debugger per vedere la traccia dello stack? – sth

+3

ci sono molti casi d'uso in cui non è possibile fare questo – Coren

risposta

2

Vedi backtrace().

ad es.

#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; 
} 

uscita:

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 

See:

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

4

Avete le funzioni backtrace in glibc. Può consentire di avere traccia completa, con la funzione o il metodo del chiamante.

Se si desidera solo il chiamante, c'è anche specific functions in gcc proprio per questo:

__builtin_frame_address(int level); 

Con level == 1 si ha la funzione chiamante. Vedi this post per ulteriori dettagli su come usarlo.

Ecco il programma di esempio che è nella documentazione:

#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

Trovo conveniente anche emettere i risultati di 'backtrace' stesso (i puntatori grezzi). È quindi possibile utilizzare l'utilità della riga di comando 'addr2line' per convertirlo in nomi di file e numeri di riga di origine reale. –

+0

Grazie mille. Ma come ottenere il nome della funzione? Questo sembra solo stampare alcuni indirizzi. Perdonate la mia ignoranza. – user984260

+0

Nelle stringhe [i], hai il nome di funzioni e con dlinfo dell'altro link, può anche mostrarti più informazioni – Coren

Problemi correlati