(EDIT) Environment:
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"
I have been working on a server-side project. I use boost libraries, such as, boost::asio
, boost::shared_ptr
, and boost::weak_ptr
.
The Boost documentation (http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm#lock) says that the weak_ptr<T>.lock
never throws:
lock
shared_ptr lock() const; Returns: expired()? shared_ptr(): shared_ptr(*this).
Throws: nothing.
However, in my application, it's even crashed:
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
I checked the line crashed in /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 }
The line 92 is assembly code. I really don't know what that means.
I always do the check if the returned boost::weakptr<RtmpConnection>.lock()
(type of boost::shared_ptr<RtmpConnection>
is empty before I used it.
So I googled, I saw this 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
- So what should I do to deal with it, why does it crash (it seems
boost::weakptr<RtmpConnection>.lock()
should never crash)? - Since my program is multithreaded. It's possible that after I get and check the returned value of
boost::weakptr<RtmpConnection>.lock()
, theRtmpConnection
might be destroyed by other thread, does the Boost Library guarantee that it won't be destroyed, because the return type isboost::shared_ptr<RtmpConnection>
?
Most likely, you are violating one of the rules for proper use of smart pointers. Here are the most common smart pointer rules violations:
An object must only be referenced through a single chain of smart pointers. Ideally, create a smart pointer with the object using
make_shared
and never use a raw pointer. But otherwise, create a smart pointer from a regular pointer only once.Only create a weak pointer from the object's strong pointer. (Or you can use
shared_from_this
if the object supports it.)An object must not be destroyed by calling
delete
while a smart pointer refers to it. Ideally, you would never calldelete
on an object that ever had any kind of smart pointer refer to it.There are two other typical causes of problems like this. One is that you have a bug causing memory corruption such as array bounds overwrite, double free, access after free, and so on. You can check for a memory corruption bug with a tool like
valgrind
.Lastly, you may have compiled your code incorrectly or compiled Boost incorrectly. For example, your platform might have compiler options that need to be enabled to compile thread-safe code. (You didn't mention your platform, so I can't give you specifics.)