代码之家  ›  专栏  ›  技术社区  ›  Idan K

分配std::string时死锁

  •  0
  • Idan K  · 技术社区  · 15 年前

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

    #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,您会看到在我自己的异常类中包装的坏分配被捕获,然后创建另一个字符串。

    另一条线是:

    #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
    

    有人能提供比我目前收集到的更多的见解吗?

    2 回复  |  直到 15 年前
        1
  •  2
  •   cmeerw    15 年前

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

    我猜发生的事情是std::\u default\u alloc\u模板递归使用是不安全的——很可能是因为它在第16-18帧(使用非递归互斥)中锁定了一些数据结构,并试图重新获取第6帧中的同一互斥(由于它不是递归互斥而死锁)。

        2
  •  0
  •   Kirill V. Lyadvinsky    15 年前

    你的问题和 this -D_PTHREADS -D_REENTRANT . 希望这会有帮助。