C++ 分配std::字符串时发生死锁

C++ 分配std::字符串时发生死锁,c++,linux,multithreading,stl,deadlock,C++,Linux,Multithreading,Stl,Deadlock,我有一个运行了几个线程的应用程序。我有两个线程在试图分配std::string时似乎处于死锁状态。检查这两个线程的回溯表明,在某个时候,有人试图分配一个std::string,但得到了一个错误的\u alloc异常。在catch块中,创建另一个字符串,试图将调用堆栈写入某个日志文件。同时,另一个线程也在尝试分配一个std::string,然后整个进程就陷入了困境 以下是2个死锁线程的相关部分: #0 0x004cf7a2 in _dl_sysinfo_int80 () from /lib/ld

我有一个运行了几个线程的应用程序。我有两个线程在试图分配std::string时似乎处于死锁状态。检查这两个线程的回溯表明,在某个时候,有人试图分配一个std::string,但得到了一个错误的\u alloc异常。在catch块中,创建另一个字符串,试图将调用堆栈写入某个日志文件。同时,另一个线程也在尝试分配一个std::string,然后整个进程就陷入了困境

以下是2个死锁线程的相关部分:

#0  0x004cf7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1  0x034ba3de in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#2  0x034b700b in _L_mutex_lock_35 () from /lib/tls/libpthread.so.0
#3  0x004e5fd4 in ?? () from /lib/ld-linux.so.2
#4  0x07c9f9bc in ?? () from /.../libstdc++.so.5
#5  0x00000037 in ?? ()
#6  0x07ca1714 in std::__default_alloc_template<true, 0>::_S_free_list () from /.../libstdc++.so.5
#7  0x9b2223a8 in ?? ()
#8  0x07c6ab7e in std::__default_alloc_template<true, 0>::allocate () from /.../libstdc++.so.5
#9  0x07c6ab7e in std::__default_alloc_template<true, 0>::allocate () from /.../libstdc++.so.5
#10 0x07c70b68 in std::string::_Rep::_S_create () from /.../libstdc++.so.5
#11 0x081c5ec0 in std::string::_S_construct<char*> ()
#12 0x081c33a2 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*> ()
#13 0x081c296e in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str ()
#14 0x02af7d7a in os::bad_allocation_t::bad_allocation_t () from /.../libmylib.so 
#15 0x02af84a9 in operator new () from /.../libmylib.so 
#16 0x07c6b0f1 in std::__default_alloc_template<true, 0>::_S_chunk_alloc () from /.../libstdc++.so.5
#17 0x07c6affd in std::__default_alloc_template<true, 0>::_S_refill () from /.../libstdc++.so.5
#18 0x07c6ab6c in std::__default_alloc_template<true, 0>::allocate () from /.../libstdc++.so.5
#19 0x07c78b2f in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_S_create () from /.../libstdc++.so.5
#20 0x07c78c59 in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_M_clone () from /.../libstdc++.so.5
#21 0x07c76996 in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::reserve () from /.../libstdc++.so.5
#22 0x07c76cff in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::append () from /.../libstdc++.so.5
来自/lib/ld linux.so.2的_dl_sysinfo_int80()中的0 0x004cf7a2 #1 0x034ba3de位于/lib/tls/libpthread.so.0中的uu llu mutex\u lock\u wait() #2 0x034b700b位于/lib/tls/libpthread.so.0中的互斥锁35()中 #3 0x004e5fd4英寸??()来自/lib/ld linux.so.2 #4 0x07c9f9bc英寸??()from/../libstdc++.so.5 #5 0x00000037英寸??() #标准中的6 0x07ca1714::\u默认值\u分配\u模板::\u自由\u列表()来自/../libstdc++.so.5 #7 0x9b2223a8英寸??() #标准中的8 0x07c6ab7e::uuu default_ualloc_template::allocate()from/../libstdc++.so.5 #9 0x07c6ab7e在std::uuu default_alloc_template::allocate()from/../libstdc++.so.5中 #std::string::_Rep::_S_create()from/../libstdc++.so.5中的10 0x07c70b68 #std::string::_S_构造()中的11 0x081c5ec0 #标准::基本字符串::基本字符串()中的12 0x081c33a2 #标准中的13 0x081c296e::基本字符串BUF::str() #操作系统中的14 0x02af7d7a::bad_分配\u t::bad_分配\u t()来自/../libmylib.so #来自/../libmylib.so的运算符new()中的15 0x02af84a9 #16 0x07c6b0f1,标准::_默认值_alloc_模板::_S_chunk_alloc()from/../libstdc++.so.5 #标准中的17 0x07c6affd::uu默认值_u分配模板::u S_u重新填充()/../libstdc++.so.5 #18 0x07c6ab6c在std::uuu default_alloc_template::allocate()from/../libstdc++.so.5中 #std::basic_string::_Rep::_S_create()from/../libstdc++.so.5中的19 0x07c78b2f #std::basic_string::_Rep::_M_clone()from/../libstdc++.so.5中的20 0x07c78c59 #std::basic_string::reserve()中的21 0x07c76996来自/../libstdc++.so.5 #std::basic_string::append()from/../libstdc++.so.5中的22 0x07c76cff 在#14,您会看到在我自己的异常类中包装的bad#u alloc被捕获,然后创建另一个字符串。
在#15,您会看到我自己的运算符new,它只调用std::malloc,检查其返回,并在NULL时抛出bad_分配

另一条线:

#0  0x004cf7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1  0x034ba3de in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#2  0x034b700b in _L_mutex_lock_35 () from /lib/tls/libpthread.so.0
#3  0x18f54584 in ?? ()
#4  0x07c9f9bc in ?? () from /.../libstdc++.so.5
#5  0x00000033 in ?? ()
#6  0x07ca1714 in std::__default_alloc_template<true, 0>::_S_free_list () from /.../libstdc++.so.5
#7  0x9b4236c8 in ?? ()
#8  0x07c6ab7e in std::__default_alloc_template<true, 0>::allocate () from /.../libstdc++.so.5
#9  0x07c6ab7e in std::__default_alloc_template<true, 0>::allocate () from /.../libstdc++.so.5
#10 0x07c78b2f in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_S_create () from /.../libstdc++.so.5
#11 0x07c78c59 in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_M_clone () from /.../libstdc++.so.5
#12 0x07c76996 in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::reserve () from /.../libstdc++.so.5
#13 0x07c76cff in std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::append () from /.../libstdc++.so.5
来自/lib/ld linux.so.2的_dl_sysinfo_int80()中的0 0x004cf7a2 #1 0x034ba3de位于/lib/tls/libpthread.so.0中的uu llu mutex\u lock\u wait() #2 0x034b700b位于/lib/tls/libpthread.so.0中的互斥锁35()中 #3 0x18f54584英寸??() #4 0x07c9f9bc英寸??()from/../libstdc++.so.5 #5 0x00000033英寸??() #标准中的6 0x07ca1714::\u默认值\u分配\u模板::\u自由\u列表()来自/../libstdc++.so.5 #7 0x9b4236c8英寸??() #标准中的8 0x07c6ab7e::uuu default_ualloc_template::allocate()from/../libstdc++.so.5 #9 0x07c6ab7e在std::uuu default_alloc_template::allocate()from/../libstdc++.so.5中 #std::basic_string::_Rep::_S_create()from/../libstdc++.so.5中的10 0x07c78b2f #std::basic_string::_Rep::_M_clone()from/../libstdc++.so.5中的11 0x07c78c59 #std::basic_string::reserve()中的12 0x07c76996来自/../libstdc++.so.5 #std::basic_string::append()from/../libstdc++.so.5中的13 0x07c76cff
有谁能提供比我目前收集到的更多的见解吗?

您的问题与我的问题非常相似。确保已指定
-D_PTHREADS
-D_retentrant
。希望这会有所帮助。

尝试从新操作符中创建动态分配的字符串可能是一个非常糟糕的主意(尤其是在无法分配内存之后)


我猜现在发生的是std::_default_alloc_模板递归使用是不安全的-很可能是因为它在第16-18帧中锁定了一些数据结构(使用非递归互斥),并试图在第6帧中重新获取相同的互斥(由于它不是递归互斥,所以会死锁).

但在这种情况下,默认分配模板的第一个参数为true,这是一个好的迹象。在gcc 3.3.3中(似乎在此版本之后STL分配器中有一些更改),确实存在一些导致死锁的默认分配模板锁定。