代码之家  ›  专栏  ›  技术社区  ›  Flinkman

我需要在我的userland代码中找到崩溃内核的点

  •  0
  • Flinkman  · 技术社区  · 16 年前

    我有一个大系统,使我的系统很难崩溃。当我启动时,我甚至没有 科雷登如果我记录每一行 执行直到我的系统崩溃。我会找到那个邪恶的密码。

    我可以把gdb中的每个源代码行都记录到一个文件中吗?

    更新:

    好的,我找到了虫子。这太讨厌了。我启动的应用程序没有 关闭系统。在了解了使用mdb进行coredump检查和一些gdb步骤之后,我发现导致转储的系统调用没有实现。将系统更新到最新内核将解决我的问题。谢谢大家。

    我的教训:

    确保您知道哪个进程导致了coredump。这并不总是你开始的。

    4 回复  |  直到 16 年前
        1
  •  2
  •   Ori Pessach    16 年前

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

    我经常尝试尽可能多地消除疑点,方法是对大块代码进行注释,将系统配置为不运行某些片段(如果它允许您这样做的话)等。这相当于对问题进行特别的二进制搜索,这是一种相对快速地放大有问题代码的惊人有效方法。

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

    说到堆芯转储,请确保对堆芯转储大小没有限制(man ulimit)。

    您可以尝试使用objdump获取代码中所有函数的列表,稍微处理一下,然后在这些函数上创建一组gdb跟踪语句——基本上是自动创建gdb脚本。如果这被证明是多余的,那么使用跟踪点对代码进行二进制搜索也可以帮助您放大问题。

    别惊慌。你比虫子聪明-你会找到的。

        2
  •  2
  •   Employed Russian    16 年前

    您不能合理地使用gdb跟踪源代码的每一行(太慢)。此外,系统崩溃很可能是系统调用的结果,libc可能代表您执行系统调用。即使您找到导致操作系统崩溃的应用程序行,您仍然一无所知。

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

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

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

    或者,尝试在 user-mode Linux 或在内核上 KGDB 编译完成。

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

        3
  •  1
  •   shortbaldman    16 年前

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

    它是一个应用程序吗? 如果是,哪个应用程序?这是你自己写的申请书吗?这是你从别处得到的申请吗?如果使用调试程序,可以获得一个干净的中断吗?你能得到一个回溯显示哪些函数正在调用哪个崩溃的代码部分吗?

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

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

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

    你说你没有堆芯垃圾。您是否在您的计算机上启用了coredumps?目前大多数系统都没有默认启用coredump。

    关于记录gdb输出,您可能会获得一些成功,但这取决于问题所在,即在系统崩溃之前您是否会记录正确的输出。写入磁盘有很大的延迟。你不可能及时抓住它。

        4
  •  0
  •   Remus Rusanu    16 年前

    我不熟悉gdb实现这一点的方法,但是对于windbg,要实现这一点,需要在内核上连接一个调试器,并通过另一个调试器的串行电缆(或火线)远程控制调试器。我很肯定GDB有类似的功能,我可以很快找到一些提示: http://www.digipedia.pl/man/gdb.4.html

    推荐文章