【问题标题】:Character device driver hangs the system - how to avoid?字符设备驱动程序挂起系统 - 如何避免?
【发布时间】:2014-01-18 11:01:36
【问题描述】:

我正在编写一个简单的可写字符设备驱动程序(2.6.32-358.el6.x86_64,在 VirtualBox 下),由于它还不成熟,它往往会崩溃/冻结(段错误、无限循环)。

我正在像这样测试它:$> echo "some data" > /dev/my_dev,如果发生崩溃/冻结,整个系统 (VirtualBox) 会冻结。我试图将所有工作转移到另一个内核线程以避免系统范围内的冻结,但这没有帮助。

是否可以“隔离”这样的崩溃/冻结,以便我能够杀死内核模块在谁的上下文中运行的进程?

【问题讨论】:

    标签: linux-kernel linux-device-driver


    【解决方案1】:

    模块在内核上下文中运行。这就是为什么调试它很困难并且错误很容易使系统崩溃的原因。无限循环并不是真正的问题,因为它只会减慢系统速度,但不会导致崩溃。然而,写入错误的内存区域是致命的。

    如果你幸运的话,你会在冻结之前得到一个内核 oops。如果您在其中一个 TTY 而非 GUI 中测试您的代码,那么您可能会立即在屏幕上看到 oops(内核 BUG 日志),您可以研究这些信息和might be helpful to you

    然而,根据我的经验,最好在用户空间编写和测试独立于内核的代码,可能使用模拟函数并对其进行大量测试,在其上运行valgrind,并确保它没有错误。然后在内核空间中使用它。您会惊讶于内核模块的代码实际上可能根本不需要内核上下文。当然这在很大程度上取决于内核模块的功能。

    要在内核空间中实际调试代码,有一些我从未使用过的工具,例如 kgdb。我自己做的通常是printks 和二分搜索的混合。也就是说,如果崩溃严重到根本没有显示内核 oops。首先,我将printk(之后可能有延迟)放在不同的地方,以查看在 oops 之前到达了代码的哪些部分。 tail -f /var/log/messages 派上用场。然后,我进行二进制搜索;禁用一半代码以查看是否发生崩溃。如果不是,可能问题出在下半场。如果发生了,问题肯定出在上半年。重复!

    编写无错误内核模块的最终方法是编写一开始就没有错误的代码。当然,这几乎是不可能的,但如果你编写干净且无未定义行为的 C 代码,编写非常简洁且正确性显而易见的函数,并注意数组的边界,那就没那么难了。

    【讨论】:

    • 好吧,我正在使用printk 进行二分搜索。问题是每次“错过”都需要重新启动VB。为了得到“哎呀”,我实际上必须用CONFIG_DEBUG_INFO 重建内核,对吧?
    • @IgorR。我不知道。默认值总是对我有用。大家可以看看BUG宏是在哪里定义的,自己去检查一下。
    猜你喜欢
    • 2018-02-21
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2020-01-06
    相关资源
    最近更新 更多