调试内核关闭?

调试内核关闭?

我使用的是 Linux 4.2.0,Ubuntu 14.04 的 Ubuntu Wily HWE 内核(这就是我正在运行的)。

一个讨厌的错误在 MacBook 11,4 和 11,5 型号上,笔记本电脑实际上永远不会关闭,它们似乎到达Power down内核消息,然后挂起而不会关闭。此错误也可能会阻止挂起和恢复。有趣的是,它不会在reboot被调用时显现,仅在尝试停止机器时显现。

细节不是那么相关,但是什么相关的是我如何调试它。有没有办法strace在内核关闭时对其进行调试并以某种方式观察输出?我相当确定断电逻辑正在使系统调用永远挂起并且由于某种奇怪的原因而不会返回。如果我能找出哪个系统调用不起作用,我就可以继续找出为什么它不起作用,具体是什么硬件导致关闭失败。

是否有调试内核关闭的标准做法?我需要特殊的硬件吗?我可以为内核编写补丁,但我什至不知道从哪里开始寻找这个问题,除非我能找到不起作用的系统调用。

答案1

关于您可能需要做什么的粗略概述:

  1. 下载源代码并编译内核以启用调试(配置 -> 内核黑客)
  2. 安装kgdb补丁
  3. 通过另一台机器的串行端口连接到目标。目标可以是不同的机器,也可以是 qemu 或 bochs 等模拟器。
  4. 从源代码中,确定关闭例程
  5. 从 gdb 设置一个断点并逐步执行,直到看到挂起。

您可以通过使用 kgdb 搜索内核调试来找到有关这些步骤的更多信息。

指导可以帮助您设置调试环境。

答案2

检查内核日志:

nano /var/log/kern.log

如果关闭正确,它将包含所有相关信息,并且应该为您提供所需的调试信息。

您还可以检查 dmesg

nano /var/log/dmesg

您还将看到以前启动/关闭时的备份,这些备份将像这样附加

dmesg.0 kern.log.1

那里也有更久远的档案。

您可以通过在内核中添加更多选项来使这些内容更加详细:

  • CONFIG_PRINTK_TIME - 将时间戳添加到 dmesg

  • CONFIG_DEBUG_KERNEL - 打开内核调试

  • CONFIG_DETECT_HUNG_TASK - 有助于找出导致
    内核冻结的原因

  • CONFIG_DEBUG_INFO - 确保您可以解码内核

  • CONFIG_EARLY_PRINTK

  • CONFIG_LOG_BUF_SHIFT=21 - 将内核缓冲区日志大小设置为
    最大缓冲区

  • CONFIG_NETCONSOLE=m - 将 netconsole 编译为模块

答案3

我猜测挂起是一个设备驱动程序没有从其电源状态更改调用或类似的返回中返回 - 因此除非您对 printk 很自由,否则不会有任何有用的调试消息。

要使用快速而肮脏的黑客手段来确认这一点,请将内核启动命令行中的所有非必要驱动程序(如 grub.cfg 中存在)列入黑名单 - 例如 wi-fi、网络等,然后通过电源循环进行测试以识别任何驱动程序行为不当的驱动程序代码。

相关内容