c++ - boost::weak_ptr<T>.lock() 因 SIGSEGV 段错误而崩溃

标签 c++ boost segmentation-fault shared-ptr weak-ptr

(编辑)环境:

plee@sos-build:/usr/local/include/boost$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 11.10
Release:        11.10
Codename:       oneiric

plee@sos-build:/usr/local/include/boost$ uname -a
Linux sos-build 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
plee@sos-build:/usr/local/include/boost$

plee@sos-build:/usr/local/include/boost$ cat version.hpp
//  BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
#define BOOST_LIB_VERSION "1_47"

我一直在从事服务器端项目。我使用 boost 库,例如 boost::asio , boost::shared_ptr , 和 boost::weak_ptr .

Boost 文档 ( http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm#lock ) 说 weak_ptr<T>.lock从不抛出:

lock

shared_ptr lock() const; Returns: expired()? shared_ptr(): shared_ptr(*this).

Throws: nothing.

然而,在我的应用程序中,它甚至崩溃了:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeffff700 (LWP 5102)]
0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
92      );
(gdb) 
(gdb) bt
#0  0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
#1  0x000000000066fe5c in boost::detail::sp_counted_base::add_ref_lock (this=0x7fffffffffff)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:138
#2  0x000000000068009b in boost::detail::shared_count::shared_count (this=0x7fffefffe658, r=...)
    at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:518
#3  0x0000000000691599 in boost::shared_ptr<RtmpConnection>::shared_ptr<RtmpConnection> (
    this=0x7fffefffe650, r=...) at /usr/local/include/boost/smart_ptr/shared_ptr.hpp:216
#4  0x000000000068db48 in boost::weak_ptr<RtmpConnection>::lock (this=0x7fffe0e87e68)
    at /usr/local/include/boost/smart_ptr/weak_ptr.hpp:157

我检查了在 /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp 中崩溃的线路

 69 inline int atomic_conditional_increment( int * pw )
 70 {
 71     // int rv = *pw;
 72     // if( rv != 0 ) ++*pw;
 73     // return rv;
 74
 75     int rv, tmp;
 76
 77     __asm__
 78     (
 79         "movl %0, %%eax\n\t"
 80         "0:\n\t"
 81         "test %%eax, %%eax\n\t"
 82         "je 1f\n\t"
 83         "movl %%eax, %2\n\t"
 84         "incl %2\n\t"
 85         "lock\n\t"
 86         "cmpxchgl %2, %0\n\t"
 87         "jne 0b\n\t"
 88         "1:":
 89         "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
 90         "m"( *pw ): // input (%3)
 91         "cc" // clobbers
 92     );
 93
 94     return rv;
 95 }

第92行是汇编代码。我真的不知道那是什么意思。

我总是检查是否返回了 boost::weakptr<RtmpConnection>.lock() (boost::shared_ptr<RtmpConnection> 的类型在我使用之前是空的。

所以我用谷歌搜索,我看到了这个 http://wiki.inkscape.org/wiki/index.php/Boost_shared_pointers

Weak pointers cannot be dereferenced for thread safety reasons. If some other thread destroyed the object after you checked the weak pointer for expiry but before you used it, you would get a crash

  1. 那么我应该怎么处理它,为什么它会崩溃(看起来 boost::weakptr<RtmpConnection>.lock() 应该永远不会崩溃)?
  2. 因为我的程序是多线程的。有可能在我得到并检查 boost::weakptr<RtmpConnection>.lock() 的返回值之后, RtmpConnection可能被其他线程销毁,Boost库是否保证它不会被销毁,因为返回类型是boost::shared_ptr<RtmpConnection>

最佳答案

您很可能违反了正确使用智能指针的规则之一。以下是最常见的智能指针规则违规行为:

  1. 一个对象只能通过一个智能指针链来引用。理想情况下,使用 make_shared 为对象创建一个智能指针,永远不要使用原始指针。但除此之外,仅从常规指针创建智能指针一次。

  2. 仅从对象的强指针创建弱指针。 (或者如果对象支持,您可以使用 shared_from_this。)

  3. 当智能指针引用对象时,不得通过调用delete 来销毁对象。理想情况下,您永远不会对曾经有任何类型的智能指针引用的对象调用 delete

还有其他两个典型的问题原因。一个是您有一个导致内存损坏的错误,例如数组边界覆盖、双重释放、释放后访问等等。您可以使用 valgrind 等工具检查内存损坏错误。

最后,您可能错误地编译了代码或错误地编译了 Boost。例如,您的平台可能具有编译器选项,需要启用这些选项才能编译线程安全代码。 (你没有提到你的平台,所以我不能给你细节。)

关于c++ - boost::weak_ptr<T>.lock() 因 SIGSEGV 段错误而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9948113/

相关文章:

c++ - 使用 boost 文件系统对文件进行排序

c++ - 使用多个版本的 boost

c++ - boost 语言环境不完整类型boundary_indexing<char32_t>

php - 升级Apache和PHP后某个函数导致segmentation fault

c - 为什么在c程序中出现这个段错误

c++ - 在神秘的情况下,QCoreApplication 的用户参数为空

c++ - 为范围内的所有数字返回相同值的哈希?

c++ - 隐藏结构细节的迭代器适配器

c++ - 如何只接受整数而忽略其他数据类型?

c++ - 定义/使用从预设组件构建的类(在 C++ 中)