【问题标题】:Function caller in linux kernelLinux内核中的函数调用者
【发布时间】:2011-05-07 16:19:20
【问题描述】:

有没有办法在 linux 内核中获取函数调用者?我知道 __func__ 返回正在执行的函数名。我正在寻找名为“__func__

的函数

【问题讨论】:

  • 哇哈哈。哈哈……不理智。

标签: linux-kernel linux-device-driver embedded-linux kernel kernel-mode


【解决方案1】:

您可以通过__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()

【讨论】:

  • 那是一些令人印象深刻的柔术。
  • btw:使用__builtin_return_address(0)时,不能用int i等变量替换0;否则,你会得到一些编译错误。另外,当回溯太多时要小心,例如 __builtin_return_address(10)。如果调用堆栈没有10那么深,内核就会很高兴地崩溃。
【解决方案2】:

您还可以通过调用 dump_stack() 打印整个调用堆栈内容。

【讨论】:

    【解决方案3】:

    是否需要帧指针取决于arch,IIRC。对于 x86,他们当然希望充分利用这些特性。另请注意,出于这个原因,内联可能会影响 builtin_return_address 的准确性。

    如果您只是想通过堆栈转储查看某个位置是如何到达的,最好使用dump_stack() 函数,而不是试图摆弄 builtin_return_address。

    【讨论】:

      【解决方案4】:

      要获取调用者函数名,可以使用下面的 printk 命令。

      printk("调用者是 %pF\n", __builtin_return_address(0));

      【讨论】:

      • %pF 已弃用,而 %ps 和 %pS 是首选方式
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 2017-08-27
      • 2012-07-21
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多