【问题标题】:C++11 std::shared_ptr works fine, but boost::shared_ptr crashes, what can cause this?C++11 std::shared_ptr 工作正常,但 boost::shared_ptr 崩溃,是什么原因导致的?
【发布时间】:2014-01-18 06:34:23
【问题描述】:

我有一个多线程程序(无法在此处重现——它有数千行),每次都可以与 C++11 (GCC 4.7.3) 完美配合,但在使用 C++03 时会崩溃(使用 Boost 1.53)。

具体来说,我在我的代码中用boost::atomicboost::shared_ptr 替换std::atomicstd::shared_ptr(并在GCC 中用-std=c++03 编译它)。其他代码相同。

但是,C++03/Boost 版本永远崩溃或循环。当它崩溃时,它会在这里执行:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff4dc2700 (LWP 4065)]
0x000000000043d0c8 in boost::detail::sp_counted_base::release() ()

对此的反汇编似乎是:

(gdb) disas 0x000000000043d0c8
Dump of assembler code for function _ZN5boost6detail15sp_counted_base7releaseEv:
   0x000000000043d0b0 <+ 0>:    mov    QWORD PTR [rsp-0x8],rbp
   0x000000000043d0b5 <+ 5>:    mov    ebp,0xffffffff
   0x000000000043d0ba <+10>:    mov    QWORD PTR [rsp-0x10],rbx
   0x000000000043d0bf <+15>:    mov    eax,ebp
   0x000000000043d0c1 <+17>:    sub    rsp,0x18
   0x000000000043d0c5 <+21>:    mov    rbx,rdi
=> 0x000000000043d0c8 <+24>:    lock xadd DWORD PTR [rdi+0x8],eax
   0x000000000043d0cd <+29>:    cmp    eax,0x1
   0x000000000043d0d0 <+32>:    je     0x43d0e8 <_ZN5boost6detail15sp_counted_base7releaseEv+56>
   0x000000000043d0d2 <+34>:    mov    rbx,QWORD PTR [rsp+0x8]
   0x000000000043d0d7 <+39>:    mov    rbp,QWORD PTR [rsp+0x10]
   0x000000000043d0dc <+44>:    add    rsp,0x18
   0x000000000043d0e0 <+48>:    ret    

我看到rdi 的值是0x3f9dafee19598306,它看起来不对并且未对齐(后者可能是导致崩溃的原因)。

我从未在 C++11 版本上看到任何问题(我已经在 Windows 上的 Visual Studio 2013 和 Linux 上的当前 GCC 上测试过它),但是每次我在 C 上运行它时都会发生这种情况++03 版本,所以我怀疑这是我代码中的竞争条件,或者我现在会在 C++11 版本中看到它。

所以我有点困惑——boost::shared_ptrstd::shared_ptr 之间有什么区别可能导致这种情况?


更新:

我也在使用make_shared...当我避免使用make_shared 时,Linux 上的 C++11 版本无限循环(在 Windows 上仍然可以正常工作)。不知道这意味着什么。

【问题讨论】:

  • 第一个谷歌搜索段错误功能是this - 这看起来相似吗? (它提到了代码行 if( atomic_exchange_and_add( &amp;use_count_, -1 ) == 1 ) 看起来与反汇编非常相似)
  • @user3125280:这个问题看起来确实很相似,但似乎那个问题被解决为“无效”?我不确定它有什么帮助......
  • 哎呀 - 递归销毁大对象导致堆栈溢出是否仍有可能出现类似错误?
  • 您能否发布代码,显示使用 make_shared 与 c++03 代码中的 shared_ptr 构造的区别?
  • @user3125280:不能排除,我去看看。但是堆栈溢出不应该触发错误吗?并且代码几乎完全相同:new_vdeps = detail::shared_ptr&lt;Dependencies&gt;(new Dependencies());new_vdeps = detail::make_shared&lt;Dependencies&gt;();,其中 detail::make_shareddetail::shared_ptr 使用 using std::shared_ptr;using boost::shared_ptr; 等导入到 detail 命名空间中。

标签: c++ multithreading boost c++11 shared-ptr


【解决方案1】:

我想我找到了问题。

事实上,不是boost::shared_ptr,而是我代码中其他地方的boost::atomic

boost::atomic 不会自动将其值初始化为零

【讨论】:

  • std::atomic 也没有 - 所以这不可能是两个版本之间的区别。
  • @Casey:你确定吗?我看到_Atomic() _NOEXCEPT : _My_val() { /* default constructor */ }
  • Straight from the horses mouth "shared_ptr 原子访问...部分[实现]"。由于它在同一个文档中说它使用 boost::share_ptr 代码,因此可能存在问题(libstdc++ 程序员可能已更改)。
  • @user3125280:我认为“原子访问”可能是指std::atomic_xxx(shared_ptr *, shared_ptr),而不是我使用的。
  • @Casey:好吧,我写代码的时候没有看标准,我只是看看我面前的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2014-09-08
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 2013-06-12
相关资源
最近更新 更多