2017-02-12 10 views
-2

Не могли бы вы предоставить мне какой-либо пример Как проверить, что функция X() вызывается из функции Y() не из функции Z()?Как проверить, что функция X() вызывается из функции Y() не из функции Z()?

Использование 'C' или языка ассемблера?

Заранее спасибо.

Обновление: 02-03-2015

  1. Пусть исходный код ядра существует так много водителей призывают те же функции, как и исходный код драйвера SPI (Serial Phepheral Interface) и GPIO (Общий выходной ток назначения) вызывает одну и ту же функцию: «bzero()».

    void bzero (void * s, size_t n);

  2. Я собираюсь протестировать драйвер SPI и GPIO (код драйвера не может быть изменен). Для этого я написал тестовый драйвер. Я могу только вызвать функцию, открытую из моего тестового драйвера.

    uint8_t SPI_read_write (uint8_t byte_out, символ * s) // Функция 1 { bzero (s, SizeOf (struct_global1)); return byte_in; }

    uint8_t GPIO_read_write (uint8_t byte_out, символ * с) // Функция 2 { bzero (с, SizeOf (struct_global2)); return byte_in; }

    INT основной() // Тест драйвер { SPI_read_write (arg1, arg2); // Когда эта функция вызывается из тест-пилота он будет вызывать bzero
    }

  3. Оба finction SPI_read_write() и функция GPIO_read_write() вызывает функцию «bzero». Мне нужно, чтобы «bzero» вызывался в любом случае только из функции SPI_read_write().

Обновление 15-04-2017

Я не в состоянии получить какую линию неясно? некоторую функцию fun1() можно вызывать из N числа другой функции. как определить, какая функция называется fun1()?

Вероятно, это связано с стека, ссылка регистра ...

+2

Сделать это статической функцией в той же системе перевода, что и 'X'. Если 'Y' тоже есть, вам не повезло. Но, честно говоря, я думаю, что это (буквально) проблема [XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – StoryTeller

+0

Вы можете проверить это, используя отладчик, например. встроенный отладчик из блоков Code ::. –

+0

Проверьте его, используя '__builtin_return_address'? – Jester

ответ

2

Там нет никакого способа определить имя функции, который вызывает вашу функцию. Это полностью по дизайну, поскольку функции предназначены для предоставления абстракции, которая инкапсулирует вычисление или деятельность, не зависящую от сайта вызова. Поэтому, если вы хотите узнать, какая функция вызывает вашу функцию, вызывающая сторона должна предоставить эту информацию.

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

#define X() x(__func__) 

void x(const char* caller) { 
    printf("x() is called from %s()\n", caller); 
} 
void y() { 
    X(); 
} 
void z() { 
    X(); 
} 

Вышеуказанные отпечатки

x() is called from y() 
x() is called from z() 

Demo.

+0

Что такое GNU? Вы используете '__func__', который является предопределенным идентификатором в C99 и более поздних версиях. Тем не менее, нет ничего, что могло бы помешать пользователю писать void Z (void) {X ("Y"); } ', которые описывают функцию, называемую' Y'. –

+0

@JonathanLeffler Большое спасибо за комментарий. – dasblinkenlight

0
#include <execinfo.h> 
#include <stdio.h> 

void print_function(void *p) { 
    char cmd[128]; 
    FILE *fp; 
    snprintf(cmd, sizeof(cmd), "addr2line -e %s -f %p", "print_caller", p); 
    fp = popen(cmd, "r"); 
    if (fp) { 
     char buf[128]; 
     while (fgets(buf, sizeof(buf), fp)) { 
      printf("%s", buf); 
     } 
    } 
} 

void Y() 
{ 
    print_function(__builtin_return_address(0)); 
} 

void X() 
{ 
    Y(); 
} 

int main() 
{ 
    X(); 
    return 0; 
} 

$ gcc -g -o print_caller print_caller.c 
$ ./print_caller 
X 
/home/viswesn/print_caller.c:24 

Я также рекомендовал бы вам просматривать м страницу BACKTRACE(), которая может предоставить вам больше информации о том, как просматривать функции, которые были вызваны, прежде чем войти в текущую функцию.

+0

Спасибо. Здесь вы пишете свою собственную функцию. Вызов, как вы хотите. Итак, в этом случае я могу поставить debug msg, чтобы увидеть, какая функция называется какой функцией? верный? – RFK

+0

Фактически .. В моем случае я не могу изменить какую-либо функцию. Это правило большого пальца. Я могу вызвать функцию X() или функцию Y(), но не разрешено редактировать. – RFK