分配 std::string 时出现死锁

发布于 2024-09-16 13:32:45 字数 3831 浏览 4 评论 0原文

我有一个正在运行多个线程的应用程序。我有 2 个线程在尝试分配 std::string 时似乎陷入僵局。检查两个线程的回溯表明,在某个时刻,有人尝试分配 std::string,并得到了 bad_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

在 #14 中,您会看到包含在我自己的异常类中的 bad_alloc 被捕获,然后创建另一个字符串。
在#15,你会看到我自己的运算符 new,它只是调用 std::malloc,检查其返回并在 NULL 时抛出 bad_allocation_t

另一个线程:

#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

任何人都可以提供比我迄今为止收集到的更多的见解吗?

I have an application with several threads running. I have 2 threads that seem deadlocked when trying to allocate an std::string. Inspecting the backtrace of both threads suggest that at some point one has tried to allocate an std::string, and got a bad_alloc exception. In its catch block, another string is created in an attempt to write a call stack to some log file. At the same time, the other thread is also trying to allocate an std::string and then the whole process gets stuck.

Here are the relevant parts of the 2 deadlocked threads:

#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

At #14 you see bad_alloc wrapped in my own exception class being caught and then another string being created.
At #15 you see my own operator new which simply calls std::malloc, checks its return and throws bad_allocation_t when NULL

And the other thread:

#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

Can anyone provide any more insight than what I've gathered so far?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山人契 2024-09-23 13:32:45

尝试从 new 运算符中创建动态分配的字符串可能是一个非常糟糕的主意(特别是在无法分配内存之后)。

我猜发生的情况是 std::__default_alloc_template 不能安全地递归使用 - 很可能是因为它锁定了帧 16-18 中的某些数据结构(使用非递归互斥体)并尝试在帧 6 中重新获取相同的互斥体(这会死锁,因为它不是递归互斥体)。

Trying to create a dynamically allocated string from within your new operator is probably a very bad idea (particularly after you were unable to allocate memory).

I guess what's happening is that std::__default_alloc_template is not safe to be used recursively - most likely because it has locked some data structure in frames 16-18 (with a non-recursive mutex) and tries to reacquire that same mutex in frame 6 (which deadlocks because it's not a recursive mutex).

榕城若虚 2024-09-23 13:32:45

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

Your issue is very similar to this one. Ensure that you've specified -D_PTHREADS and -D_REENTRANT. Hope this will help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文