如何调试内核中的死锁问题

时间:2012-02-05 05:55:42

标签: debugging linux-kernel linux-device-driver kernel

我有一个错误的内核模块,我正在尝试修复。基本上,当此模块运行时,它将导致其他任务挂起超过120秒。由于几乎所有挂起的任务都在等待mm-> mmap_sem或某些文件系统锁(i_node-> i_mutex)我怀疑它与此模块有关,并没有抓住mmap_sem锁和一些文件 - 系统级别锁定(如inote-> i_mutex)按顺序,可能会导致一些死锁问题。由于我的模块不会尝试直接获取这些锁,我认为这是我调用的一些函数来抓住这些锁。现在我想弄清楚我的模块中哪些函数调用导致问题。

但是,由于以下原因,我很难调试它:

  1. 我不确切知道挂起的任务试图抓住哪个锁。我得到了挂起任务的调用跟踪,并知道它挂起的位置。内核还给我一些信息,如: “automount / 3115持有1个锁定: 0 :(& type-> i_mutex_dir_key#2){ - ..},at:[] real_lookup + 0x24 / 0xc5“。 但是,我想确切地知道任务保持哪个锁,以及它为了找出问题而确切地想要获取哪个锁。由于内核不提供函数调用的参数以及调用跟踪,因此我发现很难获得这些信息。

  2. 我正在使用gdb和vmware来调试它,这允许我设置断点,步入函数等。但是,由于哪个任务以及该任务将在什么时候挂起是一种不确定的,我真的不知道在哪里设置断点和检查。如果我能以某种方式“附加”到内核报告被阻止超过120秒的任务,并得到一些有关它的信息,那将是很棒的。

  3. 所以我的问题如下:

    1. 我可以从调用跟踪中获取调用跟踪中函数的参数,以便确切了解任务尝试抓取哪个锁。

    2. 我是否可以使用gdb以某种方式“附加”到内核中的挂起任务?如果没有,我是否有办法至少检查代表该任务的数据结构?因为我很难检查内核中的所有全局数据结构。 GDB总是抱怨“无法访问内存0x3200”或类似的东西。

    3. 如果我可以打印内核中的每个任务,他们当前持有什么锁,这也会非常有用。有办法吗?

    4. 非常感谢!

3 个答案:

答案 0 :(得分:3)

没有直接回答你的问题,但希望这更有帮助 - Linux内核有一个名为lockdep的内置重型锁定验证器。打开它让它运行。如果您遇到锁定订单问题,很可能会抓住它并为您提供详细的报告。

请参阅:http://www.mjmwired.net/kernel/Documentation/lockdep-design.txt

答案 1 :(得分:2)

内核功能lockdep可以在这方面为您提供帮助。查看我在内核中如何使用它的帖子:How to use lockdep feature in linux kernel for deadlock detection

答案 2 :(得分:1)

让我试试。 1)尝试KGDB

2)你的意思是一个挂起的过程? http://www.ibm.com/developerworks/aix/library/au-unix-strace.html

3)尝试使用lsof包。