我需要在我的用户态代码中找到导致内核崩溃的点

时间:2009-05-16 03:53:19

标签: debugging gdb

我的大系统让我的系统崩溃了。当我启动时,我甚至都没有 一个coredump。如果我记录每一行 执行直到我的系统崩溃我会找到邪恶的代码。

我可以将GDB中的每个源代码行记录到文件中吗?

更新:

好吧,我发现了这个错误。这很讨厌。我开始的应用程序没有 取下系统。在了解了使用mdb进行coredump检查之后,以及一些gdb步骤我发现导致转储的系统调用没有实现。将系统更新到最新内核将解决我的问题。感谢大家。

我的教训:

确保您知道什么过程导致coredump。它并不总是你开始的那个。

4 个答案:

答案 0 :(得分:2)

听起来像一个棘手的小问题。

我经常尝试通过注释掉大块代码,将系统配置为不运行某些部分(如果它允许你这样做)来消除尽可能多的可疑嫌疑人。这相当于做了一个特别的事情。对问题进行二分搜索,这是一种相对快速地放大违规代码的一种非常有效的方法。

日志记录的一个潜在问题是在系统锁定之前日志可能没有到达磁盘 - 如果没有获得核心转储,则可能无法获取日志。

说到核心转储,请确保您的核心转储大小没有限制(man ulimit。)

您可以尝试使用objdump获取代码中所有函数的列表,稍微处理它并在这些函数上创建一堆GDB跟踪语句 - 基本上自动创建GDB脚本。如果结果是矫枉过正,那么使用跟踪点对代码进行二进制搜索也可以帮助您放大问题。

不要惊慌。你比错误聪明 - 你会找到它。

答案 1 :(得分:2)

您无法使用GDB合理跟踪源代码的每一行(太慢)。此外,系统崩溃很可能是系统调用的结果,而libc可能代表您进行系统调用。即使您发现导致操作系统崩溃的应用程序行,您仍然不知道任何事情。

您应首先澄清哪个操作系统崩溃了。对于Linux,您可以尝试以下方法:

strace -fo trace.out /path/to/app

重新启动后,trace.out将包含应用程序在崩溃之前正在执行的系统调用。如果你很幸运,你会看到最后一次死亡系统,但我不会指望它。

或者,尝试在user-mode Linux上或在编译为KGDB的内核上重现崩溃。

这些将告诉你内核中的问题在哪里。在您的应用程序中查找匹配的系统调用可能很简单。

答案 2 :(得分:1)

请澄清您的问题:系统的哪个部分崩溃?

这是申请吗? 如果是这样,哪个应用?这是您自己编写的应用程序吗?这是您从其他地方获得的申请吗?如果使用调试器,可以获得干净的中断吗?你能获得一个回溯,显示哪些函数正在调用崩溃的代码段吗?

这是一个新的硬件驱动程序吗? 它是基于较老的司机吗?如果是这样,发生了什么变化?它是基于制造商的数据表吗?该数据表是最新且最正确的吗?

它在内核中的某个地方吗?哪个内核?

什么是操作系统?我假设它是linux,看到你正在使用GNU调试器。但当然,这不一定是这样。

你说你没有coredump。你在机器上启用了coredump吗?如今,大多数系统都没有默认启用coredump。

关于记录GDB输出,您可能会取得一些成功,但这取决于问题在于您是否在系统崩溃之前记录了正确的输出。写入磁盘有很多延迟。你可能无法及时发现它。

答案 3 :(得分:0)

我不熟悉gdb这样做的方法,但是使用windbg的方法是将调试器连接到内核并通过串行电缆(或火线)从第二个调试器远程控制调试器。我很确定gdb有类似的功能,我可以在这里快速找到一些提示:http://www.digipedia.pl/man/gdb.4.html