2010-07-26 10 views
9

Quiero saber si hay alguna forma de saber dónde se llamaba la función actualmente en ejecución, esto es, en qué archivo y línea. Estoy usando el lenguaje C, y estoy buscando algo similar a las macros __FUNCTION__, __LINE__ o __FILE__.Cómo saber qué función llama a otra

+1

Puede lograr esto mediante el uso de macros. Mira mi solución. – bits

+0

Si realmente desea que esto sea información que puede usar en su código, esa es una solicitud inusual. ¿Por qué quieres esto? Tal vez podamos ayudarlo a resolver cualquier problema que haya provocado esta pregunta. – WillfulWizard

Respuesta

11

Cambiar el nombre de su función

void Function(param1) 
{ 
} 

a

void Function_debug(param1, char * file, char * func, unsigned long line) 
{ 
} 

Entonces # define una macro de esta manera:

#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__) 
+1

Y, por cierto, eso significa que su código de cliente no cambiará. – bits

+1

Oh, realmente es una forma hermosa y fácil de hacerlo. Muchas gracias Sérgio –

+1

Si realmente desea agradecer a las partes debe hacer clic en la casilla a la izquierda de su respuesta para decir que es la que resolvió su problema. – WillfulWizard

3

No hay nada en la C que pueda proporcionarle esta información. Puede rastrear la información usted mismo (al ingresar/salir) o confiar en las API específicas de la plataforma para recorrer la pila de llamadas y determinar la función de llamada, pero no mucho más.

0

Si necesita saberlo en tiempo de ejecución, no creo que sea posible.

Si lo que necesita saber que en debugtime, se puede colocar un punto de interrupción en la función que desea, y luego, usando GDB (usando bt de comandos) o depurador de vistual de estudio, inspeccionar el seguimiento de la pila actual.

2

__FILE__, __LINE__ etc. son macros de preprocesador que se pueden ampliar fácilmente al valor correcto en tiempo de compilación. Una función puede ser llamada desde muchos lugares posibles, por lo que no se puede hacer a través del preprocesador. Encontrar el nombre de la persona que llama sería muy difícil; implica caminar la pila y hacer coincidir las direcciones con los símbolos.

Si se puede vivir con un pequeño corte, esto podría funcionar (no probado):

/* Add a called argument to your function */ 
void _myFunction(char *caller, int more_args) 

/* And define a macro that adds it automagically */ 
#define myFunction(a) _myFunction(__FUNCTION__, a) 
0

Esto es en realidad un poco más complicado de hacer. Su mejor opción es obtener un seguimiento en un depurador o encontrar algo similar a pstack para su plataforma. La forma manual implicaría atravesar la pila de llamadas y usar símbolos de depuración para traducir eso a archivos y líneas.

0

Puede usar registros.

#define BEGIN_FUNC(X,Y,Z) printf("Function %s Entered at line %d from file %s",X,Z,Y) 
#define END_FUNC(X) printf("Function %s Exited at line %d from file %s",X,Z,Y) 

foo() 
{ 
BEGIN_FUNC(__func__,__FILE__,__LINE__); 

//Your code here 


END_FUNC(__func___FILE__,__LINE__); 

}

O

Uso bt en GDB. Yo lo llamo atrás.

1

No hay nada que sea compatible con todas las implementaciones que harán lo que usted desee. He encontrado de vez en cuando a mí mismo en la misma situación, donde tenía que realizar un seguimiento de las personas que llaman para algunos métodos e hizo algo como lo siguiente:

#ifdef TRACKBACK 
int foo(int arg1, int arg2, const char * file, int line) 
{ 
    SEND_TO_LOG("foo", file, line); 
#else 
int foo(int arg1, int arg2) 
{ 
#endif 
    ... 
    ... 

Por supuesto, lo convierte en un poco de un dolor de cabeza al extremo llamante, por lo que querrá hacer algo como:

#ifdef TRACKBACK 
    #define TRACKING, __FILE__, __LINE__ 
#else 
    #define TRACKING 
#endif 

Entonces la llamada:

foo(arg1, arg2 TRACKING); //note the lack of the comma 

se hace el truco cuando todo lo demás falla.

Cuestiones relacionadas