问号'是什么意思'?'在Linux内核恐慌调用跟踪?

时间:2012-10-28 21:53:12

标签: linux linux-kernel kernel backtrace panic

Call Trace包含以下条目:

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

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

1 个答案:

答案 0 :(得分:30)

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

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

'?'本身由printk_stack_address()输出。

堆栈条目可能有效或无效。有时人们可能会跳过它。 调查所涉及模块的反汇编可能会有所帮助,以查看在ClearFunctionName+0x88(或在x86上,紧接该位置之前)调用哪个函数。

关于可靠性

在x86上,当调用dump_stack()时,实际检查堆栈的函数是arch/x86/kernel/dumpstack.c中定义的print_context_stack()。看看它的代码,我将尝试在下面解释它。

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

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

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

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

如果堆栈帧的值'stack'指向的是返回地址,则该值被视为可靠的堆栈条目。将使用ops->addressreliable == 1调用printk_stack_address(),它最终将调用{{1}},并且该值将作为可靠的调用堆栈条目输出。否则该地址将被视为不可靠。无论如何它会输出但是'?'前缀。

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

具有DWARF2展开支持(以及设置为CONFIG_STACK_UNWIND)的系统是另一个故事。