每当硬件出现段错误时,Linux 内核都会执行哪些步骤。现在我知道故障处理程序通过 IDT 来处理它,并且在 kern.log (dmesg) 中的某个位置有一条关于该故障的消息。
我问这个问题是因为我正在开发一个虚拟机管理程序,每当用户空间中存在段错误(这不应该使系统崩溃)时,系统就会崩溃(崩溃仅在 kern.log 中的消息之后发生)。因此,如果我能够追溯内核在遇到段错误时所做的事情,这将对我有很大帮助。
答案1
- 拱门/x86/内核/idt.c:152-
page_fault
用于 IDT - 拱门/x86/entry/entry_64.S:1143-
page_fault
被定义为 的包装函数do_page_fault()
,使用宏实现idtentry
- 拱门/x86/entry/entry_64.S:847-
idtentry
宏 - 拱门/x86/mm/fault.c:1562-
do_page_fault()
到达 后do_page_fault()
,您应该会看到可点击的链接来导航代码的其余部分。对于前四个步骤你不能这样做,因为 Elixir 不理解宏魔法。它也不理解汇编。
如果您需要查看任何其他陷阱,则其他一些处理函数 ( do_*
) 又由另一个宏定义,x86/内核/traps.c:281 DO_ERROR()
。
记录段错误消息的函数也在fault.c中:显示信号消息()。给你一点免费赠品。 Elixir 不允许搜索一般字符串,只能搜索标识符。 GitHub 也关闭了他们的代码搜索。无论如何,在不实际下载源代码的情况下很难搜索此消息格式字符串,因为它"%s%s[%d]: segfault at %lx ip %px sp %px error %lx"
不包含很多特定的单词或短语:-)。
上面的链接是 v5.0 源代码的特定行号。使用灵丹妙药,我真的很喜欢:-)。
答案2
用户空间由内核管理和运行,因此如果用户空间内发生内核级段错误,则会影响内核。
根据日志设置、内核设置以及是否使用 systemd,每个系统的行为都会有所不同(但 dmesg 通常是主要的调试/日志位置)
在您的特定情况下,如果您知道哪个进程生成段错误,您可以使用strace
或gdb appname
调试有问题的进程。
https://wiki.archlinux.org/index.php/Step-by-step_debugging_guide本指南提供了有关如何调试段错误的更多详细信息