问号“?"的含义是什么?在 Linux 内核恐慌调用跟踪? [英] What is the meaning of question marks '?' in Linux kernel panic call traces?

查看:39
本文介绍了问号“?"的含义是什么?在 Linux 内核恐慌调用跟踪?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Call Trace 包含以下条目:

The Call Trace contains entries like that:

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

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

What is the meaning of the '?' mark before AnotherFunctionName?

推荐答案

'?'意味着有关此堆栈条目的信息可能不可靠.

'?' means that the information about this stack entry is probably not reliable.

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

The stack output mechanism (see the implementation of dump_trace() function) was unable to prove that the address it has found is a valid return address in the call stack.

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

'?' itself is output by printk_stack_address().

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

The stack entry may be valid or not. Sometimes one may simply skip it. It may be helpful to investigate the disassembly of the involved module to see which function is called at ClearFunctionName+0x88 (or, on x86, immediately before that position).

关于可靠性

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

On x86, when dump_stack() is called, the function that actually examines the stack is print_context_stack() defined in arch/x86/kernel/dumpstack.c. Take a look at its code, I'll try to explain it below.

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

I assume DWARF2 stack unwind facilities are not available in your Linux system (most likely, they are not, if it is not OpenSUSE or SLES). In this case, print_context_stack() seems to do the following.

它从一个地址(代码中的堆栈"变量)开始,该地址保证是堆栈位置的地址.它实际上是dump_stack()中一个局部变量的地址.

It starts from an address ('stack' variable in the code) that is guaranteed to be an address of a stack location. It is actually the address of a local variable in dump_stack().

该函数反复递增该地址(while (valid_stack_ptr ...) { ... stack++})并检查它指向的内容是否也可能是内核代码中的地址(if (__kernel_text_address(addr)) ...).通过这种方式,它会尝试找到调用这些函数时压入堆栈的函数的返回地址.

The function repeatedly increments that address (while (valid_stack_ptr ...) { ... stack++}) and checks if what it points to could also be an address in the kernel code (if (__kernel_text_address(addr)) ...). This way it attempts to find the functions' return addresses pushed on stack when these functions were called.

当然,并不是所有看起来像返回地址的无符号长整型值实际上都是返回地址.所以函数会尝试检查它.如果在内核代码中使用了帧指针(如果设置了 CONFIG_FRAME_POINTER,则使用 %ebp/%rbp 寄存器),它们可用于遍历函数的堆栈帧.函数的返回地址位于帧指针的正上方(即在 %ebp/%rbp + sizeof(unsigned long)).print_context_stack 正是这样做的.

Of course, not every unsigned long value that looks like a return address is actually a return address. So the function tries to check it. If frame pointers are used in the code of the kernel (%ebp/%rbp registers are employed for that if CONFIG_FRAME_POINTER is set), they can be used to traverse the stack frames of the functions. The return address for a function lies just above the frame pointer (i.e. at %ebp/%rbp + sizeof(unsigned long)). print_context_stack checks exactly that.

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

If there is a stack frame for which the value 'stack' points to is the return address, the value is considered a reliable stack entry. ops->address will be called for it with reliable == 1, it will eventually call printk_stack_address() and the value will be output as a reliable call stack entry. Otherwise the address will be considered unreliable. It will be output anyway but with '?' prepended.

[注意] 如果帧指针信息不可用(例如在 Debian 6 中默认情况下),所有调用堆栈条目将因此被标记为不可靠.

[NB] If frame pointer information is not available (e.g. like it was in Debian 6 by default), all call stack entries will be marked as unreliable for this reason.

支持 DWARF2 展开支持(并设置了 CONFIG_STACK_UNWIND)的系统完全是另一回事.

The systems with DWARF2 unwinding support (and with CONFIG_STACK_UNWIND set) is a whole another story.

这篇关于问号“?"的含义是什么?在 Linux 内核恐慌调用跟踪?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆