2010-07-26 5 views
9

Je veux savoir s'il existe un moyen de savoir où la fonction en cours d'exécution a été appelée, c'est-à-dire dans quel fichier et ligne. J'utilise le langage C, et je cherche quelque chose de similaire aux macros __FUNCTION__, __LINE__ ou __FILE__.Comment savoir quelle fonction est appelée une autre

+1

Vous pouvez y parvenir en utilisant des macros. Regardez ma solution. – bits

+0

Si vous voulez réellement que ce soit des données que vous pouvez utiliser dans votre code, c'est une requête inhabituelle. Pourquoi vous voulez ceci? Peut-être que nous pouvons vous aider à résoudre le problème qui a déclenché cette question? – WillfulWizard

Répondre

11

Renommer votre fonction

void Function(param1) 
{ 
} 

à

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

Puis #define une macro comme ceci:

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

Et btw, cela signifie que votre code client restera inchangé. – bits

+1

Oh, vraiment une façon belle et facile de le faire. Merci beaucoup Sérgio –

+1

Si vous voulez vraiment remercier les bits, vous devez cliquer sur la case à cocher à gauche de sa réponse pour dire que c'est celui qui a résolu votre problème. – WillfulWizard

3

Rien dans C lui-même ne vous donnerait cette information. Vous pouvez soit tracer les informations vous-même (à l'entrée/sortie) ou vous fier aux API spécifiques à la plate-forme pour parcourir la pile des appels et déterminer la fonction d'appel, mais pas beaucoup plus.

0

Si vous avez besoin de le savoir à l'exécution, je ne pense pas que ce soit possible.

Si vous avez besoin de le savoir à debugtime, vous pouvez placer un point d'arrêt sur la fonction que vous voulez, puis, en utilisant GDB (en utilisant la commande bt) ou le débogueur de vistual studio, inspecter le courant STACK TRACE.

2

__FILE__, __LINE__ etc sont des macros de préprocesseur qui peuvent facilement être étendues à la valeur correcte au moment de la compilation. Une fonction peut être appelée à partir de plusieurs endroits possibles, ce qui ne peut pas être fait via le préprocesseur. Trouver le nom de l'appelant serait très difficile; cela implique de parcourir la pile et de faire correspondre les adresses aux symboles.

Si vous pouvez vivre avec un petit hack, cela pourrait fonctionner (non testé):

/* 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

C'est en fait un peu plus compliqué à faire. Votre meilleur pari est d'obtenir un backtrace sur un débogueur, ou trouver quelque chose de similaire à pstack pour votre plate-forme. La méthode manuelle impliquerait de parcourir la pile des appels et d'utiliser des symboles de débogage pour les traduire en fichiers et en lignes.

0

Vous pouvez utiliser des journaux.

#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__); 

}

OU

Utilisation bt dans gdb. Je l'appelle traçabilité.

1

Il n'y a rien qui soit supporté dans toutes les implémentations qui feront ce que vous voulez. Je parfois me suis retrouvé dans la même situation, où je devais suivre les appels pour quelques méthodes et a fait quelque chose comme ce qui suit:

#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 
    ... 
    ... 

Bien sûr, il fait un peu d'un mal de tête à la fin d'appel, de sorte que vous aurez envie de faire quelque chose comme:

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

l'appel:

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

Il fait l'affaire quand tout le reste échoue.

Questions connexes