1

所以我现在几次遇到一个奇怪的错误,我正在寻找一些好的方向来识别问题。

基本上我看到的是一个段错误。症状如下:

  1. 它仅在程序处于发布模式而不是调试时发生。
  2. 它显示为段错误,GDB 告诉我它位于函数末尾的_list_release//_free()中。free()

    Program received signal SIGSEGV, Segmentation fault.

    0xb0328af8 in _list_release () from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    (gdb) bt

    0 0xb0328af8 in _list_release () from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    1 0xb032a464 in __free () from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    2 0xb0329f7d in free () from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

  3. 我没有使用任何动态内存(Eigen(或其他库)中可能出现的内存除外)

  4. 我可以在函数结束之前打印所有局部变量,所以它不是双重释放的。

上次发生这种情况时,这是一个适合所有这些问题的内存故障。恼人的是,这次我找不到问题所在。

我想做的是以下内容:

  1. 这将非常有用:如何在调试模式下强制此错误,然后 GDB 会更有帮助。
  2. 找出导致问题的小虫子的最佳方法是什么。注意:我不能使用 valgrind,它在我使用的操作系统(QNX)上不起作用

任何帮助都会很棒。

4

1 回答 1

4

它显示为段错误,GDB 告诉我它在 _list_release/_free()/free()

通常,任何崩溃free()都是堆损坏的迹象(双重释放、对已释放内存的写入、释放未分配(例如堆栈或全局)内存或堆缓冲区溢出)。

我没有使用任何动态内存

是的,你。您通过其他库间接这样做的事实是无关紧要的。

我可以在函数结束之前打印所有局部变量,所以它不是双重释放的。

正如许多评论者已经说过的那样,您的结论并不成立:您可以很好地访问释放的内存,它甚至可能仍然包含合理的值。

如何在调试模式下强制此错误,然后 GDB 会更有帮助。

  • 您可以使用“-O2 -g”(“发布”模式但启用调试信息)进行构建。
  • GDB 可能不会更有帮助——GDB 在调试堆损坏方面有点无用。

追踪什么小虫子的最佳方法是什么

你有几个选择:

  • 将您的代码移植到可以使用ValgrindAddressSanitizer的平台
  • 使用许多调试 malloc 实现之一(dmalloc、mpatrol 等)。QNX 有一个.
  • 非常仔细地阅读代码,确保您不会将更多的数据写入可能是 malloc 的缓冲区中。
于 2013-01-07T07:31:48.887 回答