Вызывающая функция в ядре Linux

Есть ли способ получить вызывающую функцию в ядре Linux? Я знаю, что __func__ возвращает имя выполняемой функции. Я ищу функцию, которая называется "__func__"


person BHS    schedule 10.11.2010    source источник
comment
Муахахахаа. Ха-ха... не в здравом уме.   -  person    schedule 10.11.2010


Ответы (4)


Вы можете получить вызывающего абонента с помощью __builtin_return_address(0).

Абонентом вызывающего абонента является __builtin_return_address(1) и так далее.

Это расширение GCC, задокументированное в руководстве gcc: http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html

Редактировать: я, вероятно, должен указать, что вы получаете адрес вызывающего абонента. Если вам нужно имя функции, вы можете напечатать его с помощью %pS, например:

printk("Caller is %pS\n", __builtin_return_address(0));

Если вы не хотите его печатать, вы можете использовать kallsyms_lookup() и т. д.

person mpe    schedule 10.11.2010
comment
Это впечатляющее джиу-джитсу. - person Eric Seppanen; 10.11.2010
comment
кстати: при использовании __builtin_return_address(0) вы не можете заменить 0 переменной, такой как int i; в противном случае вы получите ошибку компиляции. Кроме того, будьте осторожны при отслеживании слишком большого количества данных, например __builtin_return_address(10). Если стек вызовов не такой глубокий, как 10, ядро ​​благополучно рухнет. - person Jiang; 18.09.2012

Вы также можете распечатать все содержимое стека вызовов, вызвав dump_stack().

person Bandicoot    schedule 18.09.2012

Нужны ли указатели фреймов, зависит от арки, IIRC. Для x86 они, безусловно, желательны для полного использования этих функций. Также обратите внимание, что встраивание может исказить точность встроенного_return_address именно по этой причине.

Если вы просто хотите, чтобы дамп стека увидел, как было достигнуто какое-то место, лучше используйте функцию dump_stack(), чем пытаться возиться со встроенным_return_address.

person user502515    schedule 22.11.2010

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

printk("Абонент: %pF\n", __builtin_return_address(0));

person Megharaj    schedule 30.09.2015
comment
%pF устарел, а %ps и %pS предпочтительнее - person Alok Prasad; 29.05.2021