Debugging 挂起进程的内核调试?

Debugging 挂起进程的内核调试?,debugging,linux-kernel,Debugging,Linux Kernel,我试图调试一个设备驱动程序,这显然会导致其他问题 要挂起的任务。这是确定的任务或在什么时候完成 将被绞死 基本上,我从内核得到了一些错误消息,说“任务 已被阻止超过120秒”,以及一些堆栈跟踪。 挂起的任务从sendmail到mkfs再到pdflush(内核线程)。 堆栈跟踪中最顶层的函数与“getnstimeofday”不同 至“bio_submit”至“mark_locks_Hold” 我很难调试它,因为很难找到 问题。内核提供的堆栈跟踪没有多大帮助 都不是。根据那些堆栈跟踪,其中一些挂起了

我试图调试一个设备驱动程序,这显然会导致其他问题 要挂起的任务。这是确定的任务或在什么时候完成 将被绞死

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

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

所以我想知道是否有人对如何调试这样一个 问题。kgdb在这里有用吗,也许能给我确切的时间 进程挂起的点,以及它在等待什么类型的锁


任何建议都将不胜感激。

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

如果您有这样的代码:

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
...
关于如何调试您的问题,我有两个建议:

  • 知道某些调试输出是错误的,请使用您自己的代码知识来找出真正的调用堆栈。跨多个堆栈转储查找公共函数可能会有所帮助

  • 重新编译内核以使用帧指针

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

    ? printk
    ? A
    crash
    ? foo
    trouble
    

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

    如果您有这样的代码:

    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
    ...
    
    关于如何调试您的问题,我有两个建议:

  • 知道某些调试输出是错误的,请使用您自己的代码知识来找出真正的调用堆栈。跨多个堆栈转储查找公共函数可能会有所帮助

  • 重新编译内核以使用帧指针

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

    ? printk
    ? A
    crash
    ? foo
    trouble
    

    您的内核是否编译为使用帧指针?不,不是。它确实启用了所有调试选项。您的内核是否编译为使用帧指针?不,不是。它确实启用了所有调试选项。因此,我继续在启用帧指针的情况下重新编译内核。堆栈跟踪似乎仍然不太可靠…例如,我有一个堆栈跟踪显示:?互斥锁嵌套+0x13c/0x224[]互斥锁嵌套+0x143/0x224[]?实数查找+0x24/0xc5[]实数查找+0x24/0xc5,这非常可疑,因为我没有看到实数查找调用源代码中嵌套的互斥锁!(我使用的是2.6.26)@杨素丽:你可能还想看看和。所以我继续在打开帧指针的情况下重新编译我的内核。堆栈跟踪似乎仍然不太可靠……例如,我得到一个堆栈跟踪说:??互斥锁嵌套+0x13c/0x224[]互斥锁嵌套+0x143/0x224[]?真实查找+0x24/0xc5[]real_lookup+0x24/0xc5,这非常可疑,因为我没有看到real_lookup调用源代码中嵌套的互斥锁!(我使用的是2.6.26)@yangsuli:您可能还想查看并删除它。