2012-02-04 73 views
1

我正在尝试调试显然会导致其他 任务挂起的设备驱动程序。确定性是哪个任务或哪个时间会挂起。内核调试挂起进程?

基本上我从内核收到一些错误消息,说“任务有 被阻塞超过120秒”,以及一些堆栈跟踪。 挂起的任务从sendmail的变化到MKFS到将pdflush(内核线程”。 而在堆栈跟踪中最顶端的功能从改变‘getnstimeofday’ 为‘bio_submit’到‘mark_locks_held’。

我有一个硬因为很难找到 问题,内核提供的堆栈跟踪对 没有太大帮助。根据这些堆栈跟踪,一些挂起进程 甚至没有试图抓住一个锁(就像在我不知道为什么他们挂起。

所以我想知道如果有人有一些想法如何调试这样一个 问题。 kgdb是否会在这里有用,或许通过给我提供什么 点过程挂起,以及它正在等待什么样的锁?

任何建议表示赞赏。

+0

你的内核编译为使用帧指针吗? – Karmastan 2012-02-04 18:38:49

+0

不,不是。它确实有所有的调试选项。 – yangsuli 2012-02-04 18:51:33

回答

0

如果在内核中没有启用帧指针,堆栈跟踪将不可靠,并且令您感到困惑。内核要求扫描整个堆栈以获取可能是指向内核代码的指针(即潜在的返回地址)的值。这意味着过去已经返回的函数调用可能仍然会被打印。

如果您有代码是这样的:

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. 由于知道某些调试输出错误,请使用您自己的代码知识来弄清楚real调用堆栈。这可能有助于在多个堆栈转储中查找常用功能。

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

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

? printk 
? A 
crash 
? foo 
trouble 
+0

所以我继续重新编译我的内核帧指针。堆栈跟踪似乎还不是很可靠... 例如,我得到一个堆栈跟踪说: ]? 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 2012-02-04 22:43:24

+0

我更新了我的帖子以解决您的评论。 – Karmastan 2012-02-06 18:35:21

+0

@yangsuli:你可能也想看看[这里](http://lxr.linux.no/#linux+v2.6.26/fs/namei.c#L505)和[here](http:// lxr。 linux.no/#linux+v2.6.26/include/linux/mutex.h#L131)。 – Karmastan 2012-02-06 18:39:04