Как знать что функция, вызванная другой

Я хочу знать, существует ли какой-либо способ знать, где функция в настоящее время в выполнении была вызвана, это, в какой файл и строка. Я использую язык C, и я ищу что-то подобное __ ФУНКЦИЯ __, __ СТРОКА __ или __ ФАЙЛ __ макросы.

10
задан Lightness Races with Monica 1 July 2011 в 08:45
поделиться

7 ответов

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

void Function(param1)
{
}

в

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

Затем # определите такой макрос:

#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)
13
ответ дан 3 December 2019 в 20:02
поделиться

__ 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)
2
ответ дан 3 December 2019 в 20:02
поделиться

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

#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

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

1
ответ дан 3 December 2019 в 20:02
поделиться

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

0
ответ дан 3 December 2019 в 20:02
поделиться

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

3
ответ дан 3 December 2019 в 20:02
поделиться

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

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

0
ответ дан 3 December 2019 в 20:02
поделиться

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

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

}

ИЛИ

Использовать bt в GDB. Я называю это обратным следом.

0
ответ дан 3 December 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: