1

(编辑)环境:

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::asioboost::shared_ptrboost::weak_ptr.

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

shared_ptr lock() 常量;返回:过期()?shared_ptr():shared_ptr(*this)。

抛出:什么都没有。

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

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

出于线程安全的原因,不能取消引用弱指针。如果在检查弱指针是否过期但在使用它之前,其他线程破坏了该对象,则会发生崩溃

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

1 回答 1

1

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

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

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

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

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

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

于 2012-03-30T18:24:12.537 回答