【发布时间】:2012-02-27 04:02:37
【问题描述】:
我有一个错误的内核模块,我正在尝试修复它。基本上这个模块在运行的时候,会导致其他任务挂掉超过120秒。由于几乎所有挂起的任务都在等待 mm->mmap_sem 或某些文件系统锁(i_node->i_mutex),我怀疑它与此模块有关,不会获取 mmap_sem 锁和某些文件系统级别按顺序锁定(如 inote->i_mutex),这可能会导致一些死锁问题。由于我的模块并没有尝试直接获取这些锁,我假设它是我调用的某个函数来获取这些锁。现在我正试图找出我的模块中的哪个函数调用导致了问题。
但是,由于以下原因,我很难调试它:
我不知道挂起的任务正试图获取哪个锁。我得到了挂起任务的调用跟踪,并且知道它在什么时候挂起。内核还给了我一些信息,比如: “自动挂载/3115 持有的 1 个锁: 0: (&type->i_mutex_dir_key#2){--..},在:[] real_lookup+0x24/0xc5"。 但是,我想知道任务持有哪个锁,以及它试图获取哪个锁以找出问题。由于内核没有提供函数调用的参数以及调用跟踪,我发现很难获得这些信息。
我正在使用 gdb 和 vmware 来调试它,它允许我设置断点、单步执行函数等。但是,由于哪个任务以及该任务将在什么时候挂起是不确定的,我真的不知道在哪里设置断点和检查。如果我能以某种方式“附加”到内核报告被阻止超过 120 秒的任务,并获得一些关于它的信息,那就太好了。
所以我的问题如下:
我可以从哪里获得调用跟踪中的函数参数以及调用跟踪,以便准确确定任务试图获取哪个锁。
我是否可以使用 gdb 以某种方式“附加”到内核中的挂起任务?如果没有,我是否有办法至少检查代表该任务的数据结构?因为我也很难检查内核中的所有全局数据结构。 GDB 总是抱怨“无法访问内存 0x3200”或类似的东西。
如果我可以为内核中的每个任务打印出它们当前持有的锁,那也将非常有帮助。有办法吗?
非常感谢!
【问题讨论】:
标签: debugging linux-kernel linux-device-driver kernel