如果出问题了
如果您遇到的问题似乎是由于内核错误引起的,请检查文件维护者以查看是否有特定人员与您遇到麻烦的内核部分相关联。如果没有列出有任何人,那么第二个最好的办法是将它们邮寄给(torvalds@linux-foundation.org),以及可能的其他任何有关的邮件列表或新闻组。
在所有错误报告中,请告诉您您在操作的是什么内核,如何复制问题以及您的设置是什么(使用常识)。如果问题是新问题,请告诉他,如果问题是旧问题,请在首次发现问题时告诉他,他才是Linux内核最大的BOSS。
例如:
如果该错误导致显示如下消息:
unable to handle kernel paging request at address C0000010
Oops: 0002
EIP: 0010:XXXXXXXX
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
ds: xxxx es: xxxx fs: xxxx gs: xxxx
Pid: xx, process nr: xx
xx xx xx xx xx xx xx xx xx xx
或屏幕上或系统日志中的类似内核调试信息,请准确复制。转储对您来说似乎令人难以理解,但是它确实包含有助于调试问题的信息。转储上方的文本也很重要:它说明了为什么内核转储代码的原因(在上面的示例中,这是由于内核指针错误引起的)。有关寻找转储的更多信息,请参见“错误查找”
如果使用CONFIG_KALLSYMS
编译内核,则可以按原样发送转储,否则,您将不得不使用该ksymoops
程序来理解转储(但通常首选使用CONFIG_KALLSYMS
进行编译)。可以从https://www.kernel.org/pub/linux/utils/kernel/ksymoops/
下载该实用程序 。另外,您可以手动进行转储查找:
在上面的调试转储中,如果您可以查找EIP值的含义,那么它将大有帮助。这样的十六进制值对我或其他人没有太大帮助:它将取决于您的特定内核设置。您应该做的是从EIP行中获取十六进制值(忽略0010:
),然后在内核名称列表中查找该值,以查看哪个内核函数包含有问题的地址。
要找出内核函数名称,您需要找到与表现出该症状的内核相关的系统二进制文件。这是文件“ linux/vmlinux”。要提取名称列表并将其与内核崩溃时的EIP匹配,请执行以下操作:
nm vmlinux | sort | less
这将为您提供按升序排序的内核地址列表,从中可以轻松找到包含违规地址的函数。请注意,内核调试消息给出的地址不一定与功能地址完全匹配(实际上,这不太可能),因此您不能只是“ grep”列表:但是,列表将为您提供每个内核函数的起始点,因此,通过查找起始地址比您要查找的起始地址低的函数,然后查找具有较高地址的函数,可以找到所需的起始地址。实际上,在问题报告中包括一些“上下文”可能是个好主意,在有趣的地方加上几行即可。
如果由于某种原因您不能执行上述操作(您有预编译的内核映像或类似文件),请尽可能多地告诉他有关您的设置的信息。有关详细信息,请阅读“报告问题”。
另外,您可以在运行的内核上使用gdb。(只读;即,您不能更改值或设置断点。)为此,首先使用-g
编译内核;适当地编辑arch/x86/Makefile
,然后执行。您还需要启用CONFIG_PROC_FS
(通过)。
make cleanmake config
使用新内核重新引导后,请执行。现在,您可以使用所有常用的gdb
命令。查找系统崩溃点的命令是。(用EIP值替换XXXes。)
gdb vmlinux /proc/kcorel *0xXXXXXXXX
当前,对非运行内核进行gdb
操作失败,因为gdb
(错误地)无视了为其编译内核的起始偏移量。