我有一个多线程程序(这里不能重现它 - 它有成千上万行),每次使用C ++ 11(GCC 4.7.3)都可以很好地工作,但是在使用C ++ 03时它会崩溃(使用Boost 1.53)。
具体来说,我在我的代码中用std::atomic
和std::shared_ptr
代替boost::atomic
和boost::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上仍能正常工作) 。不确定这意味着什么。
答案 0 :(得分:1)
我想我发现了问题。
事实上,它不是boost::shared_ptr
,而是我的代码中的boost::atomic
。
boost::atomic
不会自动将其初始化值!