【问题标题】:What causes a Sigtrap in a Debug Session是什么导致调试会话中出现 Sigtrap
【发布时间】:2011-03-29 08:44:04
【问题描述】:

在我的 C++ 程序中,我使用了一个库,它会“发送?”特定操作的 Sigtrap 时 我正在调试它(使用 gdb 作为调试器)。然后我可以选择是要继续还是停止程序。如果我选择继续,程序按预期工作,但在捕获 Sigtrap 后设置自定义断点会导致调试器/程序崩溃。

所以这是我的问题:

  1. 是什么导致了这种 Sigtrap?它是可以删除的剩余代码行,还是由调试器“发现他不喜欢的东西”引起的?
  2. 一般来说,信号陷阱是一件坏事,如果是,为什么当我编译发布版本而不是调试版本时程序可以完美运行?
  3. Sigtrap 表示什么?

这是我昨天发布的问题的更通用方法 Boost Filesystem: recursive_directory_iterator constructor causes SIGTRAPS and debug problems。
我认为我的问题很具体,我不希望您解决我的问题,而是帮助我(希望其他人)了解背景。

非常感谢。

【问题讨论】:

  • 这可以解释无法解释的 SIGTRAP:stackoverflow.com/questions/2307621/…
  • 这个线程中的信息看起来很有希望。我正在使用的库(boost::filesystem)也需要将静态 dll 链接到程序。所以我认为我有问题,包括以错误的方式,或使用错误的 dll....

标签: c++ debugging gdb


【解决方案1】:

对于支持指令断点或数据观察点的处理器,调试器将要求 CPU 观察对特定地址的指令访问,或对特定地址的数据读/写,然后全速运行。

当处理器检测到该事件时,它会陷入内核,内核会向被调试的进程发送 SIGTRAP。通常,SIGTRAP 会终止进程,但由于它正在被调试,调试器会收到信号通知并处理它,主要是让您在继续执行之前检查进程的状态。

对于不支持断点或观察点的处理器,整个调试环境可能是通过代码解释和内存模拟来完成的,这非常慢。 (我想聪明的技巧可以通过设置页表标志来禁止读取或写入,无论哪个需要被捕获,并让内核修复页表,向调试器发出信号,然后再次限制页标志。这可能支持近- 任意数量的观察点和断点,并且在不经常访问观察点或断点的情况下运行速度稍慢。)

我在评论字段中提出的问题在这里看起来很恰当,只是因为 Windows 实际上并没有发送 SIGTRAP,而是以自己的本机方式发出断点信号。我假设当您调试程序时,会使用系统库的调试版本,并确保内存访问看起来是有意义的。您的程序中可能有一个在运行时被掩盖的错误,但实际上可能会在其他地方造成更多问题。

我还没有在 Windows 上进行过开发,但也许您可以通过查看您的 Windows 事件日志获得更多详细信息?

【讨论】:

  • 首先:感谢您的回复。它帮助我理解了 Sigtraps 背后的基本理念。我不认为我的代码有问题,不是因为我的代码太好了,而是因为我可以在一个只包含对库的 1 个方法调用的程序中触发 Sigtrap ......(我假设 boost 库不太可能包含此类缺陷)我将静态库链接到我的项目的方式可能有问题
【解决方案2】:

在使用 minGW/gcc 编译器在 Eclipse 中工作时,我意识到它对我代码中的向量的反应非常糟糕,导致 SIGTRAP 信号不明确,有时甚至显示异常的调试器行为(即在代码中的某个地方跳转并继续执行代码倒序!)。

我已将项目中的文件复制到 VisualStudio 中并解决了问题,然后将更改复制回 eclipse 和瞧,就像一个魅力。原因是向量初始化与 reserve() 和 resize() 函数的差异,或者试图访问向量数组边界之外的元素。

希望这对其他人有帮助。

【讨论】:

    【解决方案3】:

    我从调试器收到一个 SIGTRAP,发现原因是缺少返回值。

            string getName() { printf("Name!");};
    

    【讨论】:

      猜你喜欢
      • 2011-02-06
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      相关资源
      最近更新 更多