Linux内核中的函数调用者

21

在 Linux 内核中,有没有一种方法可以获取函数的调用者?我知道__func__返回正在执行的函数名称。我正在寻找调用"__func__"的函数。


2
Muahahahaaa。哈哈...不理智。 - user166390
4个回答

49
你可以使用__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()等。


9
那是一些令人印象深刻的柔术。 - Eric Seppanen
5
顺便提一句:当使用__builtin_return_address(0)时,不能将0替换为变量,例如int i;,否则会出现编译错误。此外,在追溯过程中要小心,例如__builtin_return_address(10),如果调用堆栈不够深到达10层,系统将会崩溃。 - Jiang

5

你还可以通过调用dump_stack()函数打印整个调用堆栈的内容。


4

是否需要框架指针取决于架构,如果我没记错的话。对于x86,它们肯定是要利用这些特性的。还要注意,内联可能会因为这个原因而扭曲 builtin_return_address 的准确性。

如果你只想要一个堆栈转储来查看如何到达某个位置,最好使用 dump_stack() 函数,而不是尝试与 builtin_return_address 进行操作。


0
要获取调用者函数的名称,可以使用下面的printk命令。 printk("Caller is %pF\n", __builtin_return_address(0));

%pF已被弃用,%ps和%pS是首选方式。 - Alok Prasad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接