【问题标题】:Segmentaion fault after using operator new使用 operator new 后的分段错误
【发布时间】:2013-10-24 08:44:35
【问题描述】:

我使用 linaro 工具链为 ARM 目标构建了一个 C++ 代码,该工具链专门从 ARM 硬件目标的源代码构建(使用 softfp、mtune=cortex-a9 等...) 有时,代码会因以下跟踪而崩溃。我已将 gdb 附加到正在运行的进程 显然,在调用来自 libstdc++.so.6 的新运算符后,它似乎崩溃了几个调用。

我们目前没有异常处理代码,所以如果 new 失败并抛出异常,我认为它会中止/终止,并显示如下消息:

Program received signal SIGABRT, Aborted.

但它会因 SIGSEGV 而崩溃。

为什么会这样?可能出了什么问题?

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x45c6b460 (LWP 1182)]
0x402fad12 in malloc_consolidate () from /lib/libc.so.6
#0  0x402fad12 in malloc_consolidate () from /lib/libc.so.6
#1  0x402fc498 in _int_malloc () from /lib/libc.so.6
#2  0x402fe414 in malloc () from /lib/libc.so.6
#3  0x401f54d6 in operator new(unsigned int) () from /lib/libstdc++.so.6
#4  0x400f30d4 in MyMsg::operator=(MyPkt*) () from /usr/lib/libmy-ARMV7AL.so
#5  0x400f322c in MyMsg::reply() () from /usr/lib/libmy-ARMV7AL.so
#6  0x0005a6a0 in MyManager::SendMessage (this=0x7188c8)
    at MyManager.cpp:12973
#7  0x0004389c in My::Response (this=0x7188c8)
    MyManager.cpp:5972

【问题讨论】:

  • 检查thisthis
  • 您正在某处破坏堆。 MyManager::SendMessageMyMsg::replyMyMsg::operator= 可能有一些东西。或者它可能是其他东西,很难从堆栈跟踪中分辨出来。
  • @jrok - 感谢您阅读这些链接。
  • 在问题中发布 MyManager::SendMessage() 和 My::Response () 的函数定义,我猜可能有助于您回答。

标签: c++ segmentation-fault linaro


【解决方案1】:

可能是堆损坏(解释 malloc 终止进程的原因)。

使用您的常规工具来检测未定义的行为(例如错误的内存访问)。

如果异常处理出错(在存在 ABI 压力源(如交叉编译)的情况下并不太常见),您可以使用 nothrow 版本的 operator new

X* x = new (nothrow) X;

assert(x); // or otherwise handle with care

【讨论】:

  • "使用常规工具检测未定义的行为" 。你会推荐什么工具来检查这种可能的堆损坏。我已经在相同的代码上运行了 valgrind,并且对于相同的函数 MyMsg::operator=() 它向我展示了 - “在 68 的丢失记录 26 中仍然可以访问 1 个块中的 600 个字节”,我理解这不一定是内存错误。您建议的任何其他有助于分析内存错误的工具。
  • 这是一个泄漏,表明你的类的值语义被破坏了。 Clang 有一些有用的消毒剂选项。
  • 您的意思是 valgrind 消息(1 个块中的 600 个字节在 68 条中的第 26 条丢失记录中仍然可以访问)是泄漏还是这个崩溃问题可能源于泄漏?
  • 第一个。而同样的根本原因很可能会导致其他问题,比如你的崩溃。内存泄漏本身并不一定会破坏系统(尽管在您的 ARM 机器上,您可能很快就会耗尽内存?)
【解决方案2】:

如果没有足够的内存,new 会抛出异常。但是日志中没有异常。 所以我想有足够的内存。更有可能的答案是您以某种方式破坏了内存。 你应该用 valgrind 检查你的内存访问

更困扰我的是 = 运算符的原型; MyMsg::operator=(MyPkt*)。 为什么要在对象上使用指针而不是 const 引用?或者至少一个const MyPkt const *

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    相关资源
    最近更新 更多