Блокируется при выделении std :: string - PullRequest
0 голосов
/ 01 сентября 2010

У меня есть приложение с несколькими запущенными потоками.У меня есть 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, проверяет его возврат и выдает bad_allocation_t, когдаNULL

И другой поток:

#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 ]

2 голосов
/ 02 сентября 2010

Попытка создать динамически размещаемую строку из вашего нового оператора, вероятно, очень плохая идея (особенно после того, как вы не смогли выделить память).

Я предполагаю, что std :: __ default_alloc_template не являетсябезопасно использовать рекурсивно - скорее всего потому, что он заблокировал некоторую структуру данных в кадрах 16-18 (с нерекурсивным мьютексом) и пытается повторно получить тот же мьютекс в кадре 6 (который блокируется, потому что это не рекурсивный мьютекс).

0 голосов
/ 01 сентября 2010

Ваш вопрос очень похож на этот один. Убедитесь, что вы указали -D_PTHREADS и -D_REENTRANT. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...