【发布时间】:2014-01-18 06:34:23
【问题描述】:
我有一个多线程程序(无法在此处重现——它有数千行),每次都可以与 C++11 (GCC 4.7.3) 完美配合,但在使用 C++03 时会崩溃(使用 Boost 1.53)。
具体来说,我在我的代码中用boost::atomic 和boost::shared_ptr 替换std::atomic 和std::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_ptr 和 std::shared_ptr 之间有什么区别可能导致这种情况?
更新:
我也在使用make_shared...当我避免使用make_shared 时,Linux 上的 C++11 版本无限循环(在 Windows 上仍然可以正常工作)。不知道这意味着什么。
【问题讨论】:
-
第一个谷歌搜索段错误功能是this - 这看起来相似吗? (它提到了代码行
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )看起来与反汇编非常相似) -
@user3125280:这个问题看起来确实很相似,但似乎那个问题被解决为“无效”?我不确定它有什么帮助......
-
哎呀 - 递归销毁大对象导致堆栈溢出是否仍有可能出现类似错误?
-
您能否发布代码,显示使用 make_shared 与 c++03 代码中的 shared_ptr 构造的区别?
-
@user3125280:不能排除,我去看看。但是堆栈溢出不应该触发错误吗?并且代码几乎完全相同:
new_vdeps = detail::shared_ptr<Dependencies>(new Dependencies());与new_vdeps = detail::make_shared<Dependencies>();,其中detail::make_shared和detail::shared_ptr使用using std::shared_ptr;或using boost::shared_ptr;等导入到detail命名空间中。
标签: c++ multithreading boost c++11 shared-ptr