【问题标题】:kernel debug for hung process?挂起进程的内核调试?
【发布时间】:2012-02-07 02:35:06
【问题描述】:

我正在尝试调试一个设备驱动程序,该驱动程序显然会导致其他 任务挂起。哪个任务或在什么时间它是确定性的 将挂起。

基本上我从内核收到了一些错误消息,说“任务有 被阻止超过 120 秒”,以及一些堆栈跟踪。 挂起的任务从 sendmail 到 mkfs 再到 pdflush(一个内核线程)。 堆栈跟踪中最顶层的函数与“getnstimeofday”不同 到“bio_submit”到“mark_locks_held”。

我很难调试它,因为很难找到 问题。内核提供的堆栈跟踪不是很有帮助 两者都不。根据那些堆栈跟踪,其中一些挂起的进程 甚至没有试图抓住锁(比如在 getnstimeofday 函数),我不知道他们为什么挂起。

所以我想知道是否有人对如何调试这样的 问题。 kgdb 在这里有用吗,也许可以给我确切的信息 点进程挂起,它在等待什么样的锁?

欢迎提出任何建议。

【问题讨论】:

  • 你的内核编译成使用帧指针了吗?
  • 不,不是。它确实有所有的调试选项。

标签: debugging linux-kernel


【解决方案1】:

当您没有在内核中启用帧指针时,堆栈跟踪将不可靠,这会让您感到困惑。内核求助于扫描整个堆栈以查找可能指向内核代码的值(即潜在的返回地址)。这意味着可能仍会打印已返回的过去函数调用。

如果您的代码如下所示:

void A(void) {
    printk("foo\n");
}

void B(void) {
    int x;
    A();
}

void crash(void) {
    char buf[32];
    *(int*)0 = 0;
}

void trouble(void) {
    int x;
    B();
    crash();
}

您的堆栈转储可能如下所示:

printk
A
crash
foo
trouble
...

至于如何调试你的问题,我有两个建议:

  1. 知道一些调试输出不好,利用你自己的代码知识找出真正的调用堆栈。跨多个堆栈转储查找通用函数可能会有所帮助。

  2. 重新编译内核以使用帧指针。

内核仍然会打印每个看起来像返回地址的值,但它会用“?”标记不可靠的地址。所以你的堆栈转储可能看起来像这样:

? printk
? A
crash
? foo
trouble

【讨论】:

  • 所以我继续使用帧指针重新编译我的内核。堆栈跟踪似乎仍然不太可靠......例如,我得到一个堆栈跟踪说: ] ? mutex_lock_nested+0x13c/0x224 [] mutex_lock_nested+0x143/0x224 [] ? real_lookup+0x24/0xc5 [] real_lookup+0x24/0xc5 这是非常可疑的,因为我没有看到 real_lookup 在源代码中调用 mutex_lock_nested! (我使用的是 2.6.26)
  • @yangsuli:你可能还想看看herehere
猜你喜欢
  • 1970-01-01
  • 2013-02-13
  • 2017-06-19
  • 2011-10-31
  • 1970-01-01
  • 2015-07-05
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多