【问题标题】:Segmentation Fault - how to debug? [closed]分段错误 - 如何调试? [关闭]
【发布时间】:2023-03-24 20:22:01
【问题描述】:

我的应用程序崩溃并在控制台上打印以下内容:

sh[366]: /bin/sh: line 1: 367 Segmentation fault (core dumped) ./myapp

我的问题是这里的 367 表示什么?

我无法在任何地方找到核心转储文件。
任何线索如何在这种情况下调试分段错误?

【问题讨论】:

  • ulimit 返回“无限制”但无法找到核心转储文件。
  • 使用调试器?
  • @OpenSourceEnthusiast:不要评论你的问题,而是编辑它。您的系统是否使用systemd?您是否尝试在gdb 下运行您的应用程序?你有一些minimal reproducible example(或者你的应用程序源代码的 URL)吗?

标签: linux debugging segmentation-fault


【解决方案1】:

367 是一个进程 ID(程序段错误)。您可以在gdb 调试器下运行您的程序。

阅读How To Debug Small Programs,然后阅读documentation of gdb。也可以考虑使用valgrind

任何线索在这种情况下如何调试分段错误?

如果该故障是可重现的,那就很容易了。在gdb下运行你的程序

我无法在任何地方找到核心转储文件..

仔细阅读core(5)(和getrlimit(2);也许核心转储已被某些ulimit bash 内置函数禁用)。你的系统可能被配置(见proc(5))以其他方式转储核心(例如systemd(1),可能在/var/lib/systemd/coredump/下)。或许见coredumpctl(1)systemd-coredump(8)coredump.conf(5)

不要忘记在编译您的应用程序时启用所有警告和调试信息withg++ -Wall -Wextra -g(当然,改进您的代码以完全不收到警告)。

【讨论】:

    【解决方案2】:

    通常我调试分段错误的第一步是:

    1. 使用调试符号(-g 选项)编译应用程序,但保留优化选项以避免更改过多

    2. gdb 下运行程序,在命令提示符下使用gdb --args ./myprog 后跟r

    如果你很幸运并且程序崩溃了,那么输入bt(回溯)来查看它在哪个函数中崩溃,从哪个函数调用等等直到main(或线程启动)。

    如果可能的话,更好的选择是在valgrind 下运行可执行文件,以查看它具有的第一个检测到的“不良”行为是什么。在许多情况下,像在数组边界之外读取或写入这样的坏事不会立即产生段错误,valgrid 将向您显示您不应该访问的位置上的第一次读取或写入操作(但这可以“程序正常执行时静默工作”)。使用valgrind 的缺点是执行速度非常慢,因为程序基本上使用仿真处理器运行;它太慢了,可能无法在预期的上下文中运行程序(例如,因为它需要与会超时的设备通信)。

    另一种选择是使用地址清理程序 (-fsanitize=address) 编译程序。这将在可执行文件本身中添加代码,以检查边界外的内存访问或释放的内存。优点是执行速度仍然比常规的非仪器可执行文件慢得多,但比在valgrind 下运行程序要快得多。

    【讨论】:

      【解决方案3】:

      如果核心转储不可用,GDB 甚至可以使用 .exe 文件进行调试。

      target exec -- Use an executable file as a target
      

      这样使用:

      (gdb) target exec a.exe
      

      【讨论】:

        猜你喜欢
        • 2023-03-23
        • 1970-01-01
        • 2016-09-07
        • 2013-01-06
        • 2013-05-19
        • 1970-01-01
        • 2012-01-06
        • 1970-01-01
        • 2014-10-30
        相关资源
        最近更新 更多