boost::weak_ptrlt;Tgt;.lock() Crashes with a SIGSEGV Segmentation Fault(boost::weak_ptrT.lock() 因 SIGSEGV 分段错误而崩溃)
问题描述
(编辑)环境:
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
.
I have been working on a server-side project. I use boost libraries, such as, boost::asio
, boost::shared_ptr
, and boost::weak_ptr
.
Boost 文档(http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm#lock) 说 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:
锁定
shared_ptr lock() 常量;返回:过期()?shared_ptr():shared_ptr(*this).
shared_ptr lock() const; Returns: expired()? shared_ptr(): shared_ptr(*this).
抛出:什么都没有.
但是,在我的应用程序中,它甚至崩溃了:
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
我检查了 /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
"
80 "0:
"
81 "test %%eax, %%eax
"
82 "je 1f
"
83 "movl %%eax, %2
"
84 "incl %2
"
85 "lock
"
86 "cmpxchgl %2, %0
"
87 "jne 0b
"
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 行是汇编代码.我真的不知道那是什么意思.
The line 92 is assembly code. I really don't know what that means.
我总是检查返回的 boost::weakptr
(boost::shared_ptr
的类型是否为空用过.
I always do the check if the returned boost::weakptr<RtmpConnection>.lock()
(type of boost::shared_ptr<RtmpConnection>
is empty before I used it.
所以我用谷歌搜索,我看到了这个 http://wiki.inkscape.org/wiki/index.php/Boost_shared_pointers
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
- 那我应该怎么处理呢,为什么会崩溃(似乎
boost::weakptr
应该永远不会崩溃)?.lock() - 因为我的程序是多线程的.在我获取并检查
boost::weakptr
的返回值后,.lock() RtmpConnection
可能会被其他线程破坏,Boost 是否库保证不会被销毁,因为返回类型是boost::shared_ptr
?
- 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:
一个对象只能通过一个智能指针链来引用.理想情况下,使用
make_shared
为对象创建一个智能指针,并且永远不要使用原始指针.但除此之外,只能从常规指针创建一次智能指针.
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.
仅从对象的强指针创建弱指针.(或者,如果对象支持,您可以使用 shared_from_this
.)
Only create a weak pointer from the object's strong pointer. (Or you can use shared_from_this
if the object supports it.)
当智能指针引用对象时,不能通过调用 delete
来销毁对象.理想情况下,您永远不会对曾经有任何类型的智能指针引用它的对象调用 delete
.
An object must not be destroyed by calling delete
while a smart pointer refers to it. Ideally, you would never call delete
on an object that ever had any kind of smart pointer refer to it.
此类问题还有另外两个典型原因.一个是您有一个导致内存损坏的错误,例如数组边界覆盖、双重释放、释放后访问等.您可以使用 valgrind
之类的工具检查内存损坏错误.
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
.
最后,您可能错误地编译了代码或错误地编译了 Boost.例如,您的平台可能具有编译线程安全代码需要启用的编译器选项.(你没有提到你的平台,所以我不能给你细节.)
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.)
这篇关于boost::weak_ptr<T>.lock() 因 SIGSEGV 分段错误而崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:boost::weak_ptr<T>.lock() 因 SIGSEGV 分段错误而崩溃
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01