一尘不染

问号“”是什么意思?在Linux内核中的紧急呼叫跟踪?

linux

呼叫跟踪包含如下条目:

 [<deadbeef>] FunctionName+0xAB/0xCD [module_name]
 [<f00fface>] ? AnotherFunctionName+0x12/0x40 [module_name]
 [<deaffeed>] ClearFunctionName+0x88/0x88 [module_name]

‘是什么意思?标记在AnotherFunctionName之前?


阅读 431

收藏
2020-06-07

共1个答案

一尘不染

‘?’ 表示有关此堆栈条目的信息可能不可靠。

堆栈输出机制(请参见dump_trace()函数的实现)无法证明其找到的地址是调用堆栈中的有效返回地址。

‘?’ 本身由printk_stack_address()输出。

堆栈条目可能有效还是无效。有时,人们可能只是跳过它。研究所涉及模块的拆卸以查看在哪个位置ClearFunctionName+0x88(或在x86上紧接该位置的位置)调用了哪个函数可能会有所帮助。

关于可靠性

在x86,当dump_stack()被调用时,实际检查堆栈中的功能是print_context_stack()中所定义arch/x86/kernel/dumpstack.c。看一下它的代码,我将在下面解释。

我假设DWARF2堆栈展开功能在您的Linux系统中不可用(很可能不是,如果不是OpenSUSE或SLES,则它们不可用)。在这种情况下,print_context_stack()似乎可以执行以下操作。

它从保证是堆栈位置地址的地址(代码中的“ stack”变量)开始。它实际上是中的局部变量的地址dump_stack()

该函数反复递增该地址(while (valid_stack_ptr ...) { ... stack++}),并检查其指向的内容是否也可能是内核代码(if (__kernel_text_address(addr)) ...)中的地址。这样,当这些函数被调用时,它将尝试查找推入堆栈的函数的返回地址。

当然,并非每个看起来像返回地址的无符号long值实际上都是一个返回地址。因此该函数尝试对其进行检查。如果在内核代码中使用了帧指针(如果设置了CONFIG_FRAME_POINTER,则使用%ebp
/%rbp寄存器),则可以使用它们遍历函数的堆栈帧。函数的返回地址位于帧指针的上方(即%ebp/%rbp + sizeof(unsigned long))。print_context_stack对此进行了精确检查。

如果存在一个栈帧,其值“ stack”指向的是返回地址,则该值被视为可靠的栈条目。ops->address将被调用reliable == 1,最终将被调用,printk_stack_address()并且该值将作为可靠的调用堆栈条目输出。否则,该地址将被视为不可靠。无论如何都将输出,但带有“?”
前置。

[NB]如果帧指针信息不可用(例如默认情况下在Debian 6中是这样),则出于这个原因,所有调用堆栈条目都将被标记为不可靠。

具有DWARF2展开支持(并设置了CONFIG_STACK_UNWIND)的系统则完全是另外一回事了。

2020-06-07