Oops 分析
Oops(也称 panic,慌张)消息包含系统错误的细节,如 CPU 寄存器的内容。在 Linux 中,调试系统崩溃的传统方法是分析在发生崩溃时发送到系统控制台的 Oops 消息。一旦您掌握了细节,就可以将消息发送到 ksymoops 实用程序,它将试图将代码转换为指令并将堆栈值映射到内核符号。在很多情况下,这些信息就足够您确定错误的可能原因是什么了。请注意,Oops 消息并不包括核心文件。
让我们假设系统刚刚创建了一条 Oops 消息。作为编写代码的人,您希望解决问题并确定什么导致了 Oops 消息的产生,或者您希望向显示了 Oops 消息的代码的开发者提供有关您的问题的大部分信息,从而及时地解决问题。Oops 消息是等式的一部分,但如果不通过 ksymoops 程序运行它也于事无补。下面的图显示了格式化 Oops 消息的过程。
格式化 Oops 消息
ksymoops 需要几项内容:Oops 消息输出、来自正在运行的内核的 System.map 文件,还有 /proc/ksyms、vmlinux 和 /proc/modules。关于如何使用 ksymoops,内核源代码 /usr/src/linux/Documentation/oops-tracing.txt 中或 ksymoops 手册页上有完整的说明可以参考。Ksymoops 反汇编代码部分,指出发生错误的指令,并显示一个跟踪部分表明代码如何被调用。
首先,将 Oops 消息保存在一个文件中以便通过 ksymoops 实用程序运行它。清单 10 显示了由安装 JFS 文件系统的 mount 命令创建的 Oops 消息,问题是由清单 8 中添加到 JFS 安装代码的那三行代码产生的。
|
接下来,您要确定 jfs_mount 中的哪一行代码引起了这个问题。Oops 消息告诉我们问题是由位于偏移地址 3c 的指令引起的。做这件事的办法之一是对 jfs_mount.o 文件使用 objdump 实用程序,然后查看偏移地址 3c。Objdump 用来反汇编模块函数,看看您的 C 源代码会产生什么汇编指令。清单 11 显示了使用 objdump 后您将看到的内容,接着,我们查看 jfs_mount 的 C 代码,可以看到空值是第 109 行引起的。偏移地址 3c 之所以很重要,是因为 Oops 消息将该处标识为引起问题的位置。
|
kdb
Linux 内核调试器(Linux kernel debugger,kdb)是 Linux 内核的补丁,它提供了一种在系统能运行时对内核内存和数据结构进行检查的办法。请注意,kdb 不需要两台机器,不过它也不允许您像 kgdb 那样进行源代码级别上的调试。您可以添加额外的命令,给出该数据结构的标识或地址,这些命令便可以格式化和显示基本的系统数据结构。目前的命令集允许您控制包括以下操作在内的内核操作:
处理器单步执行;
执行到某条特定指令时停止;
当存取(或修改)某个特定的虚拟内存位置时停止;
当存取输入/输出地址空间中的寄存器时停止;
对当前活动的任务和所有其它任务进行堆栈回溯跟踪(通过进程 ID);
对指令进行反汇编。
追击内存溢出
您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形。我们的小组花了许许多多时间来跟踪稀奇古怪的内存错误问题。应用程序在我们的开发工作站上能运行,但在新的产品工作站上,这个应用程序在调用 malloc() 两百万次之后就不能运行了。真正的问题是在大约一百万次调用之后发生了溢出。新系统之所有存在这个问题,是因为被保留的 malloc() 区域的布局有所不同,从而这些零散内存被放置在了不同的地方,在发生溢出时破坏了一些不同的内容。
我们用多种不同技术来解决这个问题,其中一种是使用调试器,另一种是在源代码中添加跟踪功能。在我职业生涯的大概也是这个时候,我便开始关注内存调试工具,希望能更快更有效地解决这些类型的问题。在开始一个新项目时,我最先做的事情之一就是运行 MEMWATCH 和 YAMD,看看它们是不是会指出内存管理方面的问题。
内存泄漏是应用程序中常见的问题,不过您可以使用本文所讲述的工具来解决这些问题。
第 4 种情况:使用魔术键控顺序进行回溯跟踪
如果在 Linux 挂起时您的键盘仍然能用,那请您使用以下方法来帮助解决挂起问题的根源。遵循这些步骤,您便可以显示当前运行的进程和所有使用魔术键控顺序的进程的回溯跟踪。
您正在运行的内核必须是在启用 CONFIG_MAGIC_SYS-REQ 的情况下构建的。您还必须处在文本模式。CLTR+ALT+F1 会使您进入文本模式,CLTR+ALT+F7 会使您回到 X Windows。
当在文本模式时,请按 ,然后按 。上述魔术的击键会分别给出当前运行的进程和所有进程的堆栈跟踪。
请查找 /var/log/messages。如果一切设置正确,则系统应该已经为您转换了内核的符号地址。回溯跟踪将被写到 /var/log/messages 文件中。
结束语
帮助调试 Linux 上的程序有许多不同的工具可供使用。本文讲述的工具可以帮助您解决许多编码问题。能显示内存泄漏、溢出等等的位置的工具可以解决内存管理问题,我发现 MEMWATCH 和 YAMD 很有帮助。
使用 Linux 内核补丁会使 gdb 能在 Linux 内核上工作,这对解决我工作中使用的 Linux 的文件系统方面的问题很有帮助。此外,跟踪实用程序能帮助确定在系统调用期间文件系统实用程序什么地方出了故障。下次当您要摆平 Linux 中的错误时,请试试这些工具中的某一个。
| 基于Linux操作系统实现的传真系统 | 12-09 | |
| Linux操作系统上最好的10款开源游 | 11-20 | |
| Linux 系统中的超级权限的控制 | 11-09 | |
| Linux操作系统下的常见系统资源共 | 11-07 | |
| Linux下的中文显示和支持常见问题 | 10-23 | |
| 嵌入式Linux系统的动态电源管理技 | 10-13 | |
| 从硬盘安装Linux操作系统的方法步 | 10-12 | |
| 深入浅出分析Linux设备驱动程序中 | 10-10 | |
| 使用kgdb调试linux内核及内核模块 | 10-04 | |
| 使用Linux 文本工具简化数据的提 | 10-04 | |
| 如何在Linux操作系统下检测内存泄 | 09-27 | |
| Linux内核编译菜单中相关选项的意 | 09-20 | |