Как узнать какая функция называется другой - PullRequest
10 голосов
/ 26 июля 2010

Я хочу знать, есть ли какой-нибудь способ узнать, где была вызвана выполняемая в данный момент функция, в каком файле и строке. Я использую язык C и ищу что-то похожее на макросы __FUNCTION__, __LINE__ или __FILE__.

Ответы [ 7 ]

12 голосов
/ 26 июля 2010

Переименуйте вашу функцию

void Function(param1)
{
}

в

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

Затем # определите макрос следующим образом:

#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)
3 голосов
/ 26 июля 2010

В самом C нет ничего, что могло бы дать вам эту информацию. Вы можете либо отслеживать информацию самостоятельно (при входе / выходе), либо полагаться на специфичные для платформы API для обхода стека вызовов и определения вызывающей функции, но не намного.

2 голосов
/ 26 июля 2010

__FILE__, __LINE__ и т. Д. - макросы препроцессора, которые можно легко расширить до нужного значения во время компиляции. Функция может быть вызвана из многих возможных мест, поэтому это невозможно сделать с помощью препроцессора. Узнать имя звонящего было бы очень сложно; это включает в себя обход стека и сопоставление адресов с символами.

Если вы можете жить с небольшим взломом, это может сработать (не проверено):

/* 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)
1 голос
/ 26 июля 2010

Нет ничего, что поддерживается во всех реализациях, которые будут делать то, что вы хотите. Я иногда оказывался в той же ситуации, когда мне нужно было отслеживать вызывающих абонентов для нескольких методов, и делал что-то вроде следующего:

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

Конечно, это вызывает головную боль на вызывающем конце, поэтому вы захотите сделать что-то вроде:

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

Тогда звонок:

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

Это делает трюк, когда все остальное терпит неудачу.

0 голосов
/ 26 июля 2010

Вы можете использовать журналы.

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

}

OR

Используйте bt в gdb. Я называю это следом.

0 голосов
/ 26 июля 2010

На самом деле это немного сложнее.Лучше всего получить обратную трассировку на отладчике или найти что-то похожее на pstack для вашей платформы.Ручной способ включал бы обход стека вызовов и использование символов отладки для преобразования этого в файлы и строки.

0 голосов
/ 26 июля 2010

Если вам нужно знать это во время выполнения, я не думаю, что это возможно.

Если вам нужно знать это во время отладки, вы можете установить точку останова на нужную вам функцию, а затем, используя GDB (используя команду bt ) или отладчик Vistual Studio, проверить текущую STACK TRACE.

...