【问题标题】:What is the meaning of question marks '?' in Linux kernel panic call traces?问号“?”是什么意思?在 Linux 内核恐慌调用跟踪?
【发布时间】:2017-06-24 10:41:31
【问题描述】:

呼叫跟踪包含如下条目:

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

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

【问题讨论】:

    标签: linux linux-kernel kernel backtrace panic


    【解决方案1】:

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

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

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

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

    关于可靠性

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

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

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

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

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

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

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

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

    【讨论】:

    • 很好的答案 - 它遗漏了一件事来使它完整(我对拱代码中的间接级别有点困惑) - 是什么让条目不可靠?
    • 我已经编辑了我的答案。希望我的解释不会太混乱。
    • 到达那里 :) 您的回答实际上证实了我对它如何工作的一些怀疑 - 提供一些背景信息,我正在尝试更新二进制 blob + 包装器,如驱动程序 - 所以内核实际上是我自己构建的。我感到困惑并想要一些解释的原因是,显然 blob 中的某些函数将函数指针存储在局部变量中,从而使整个系统有点混乱。请完成你的“另一个故事”——尤其是当主内核是 DWARF2 时它是如何工作的,但模块的某些部分不是。
    • 不幸的是,我绝不是 DWARF2 的专家。到目前为止,我看到的 DWARF2 展开的唯一实现是来自 SuSE Linux 的实现。据我所知,主线内核还不支持它。或者——是吗?您是否使用来自 SuSE 或其他 Linux 发行版的补丁来为您的自定义内核添加对 DWARF2 的支持?那里可能有不同的实现。
    • 此外,我看到的内核要么为所有内核模式组件启用了 DWARF2 展开,要么根本没有。目前我还不能说如果内核和模块使用不同的方法来堆栈展开会发生什么。
    猜你喜欢
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    相关资源
    最近更新 更多