Я изучаю отчет о тупике, который произошел в моей библиотеке, которая обычно многопоточна и написана на C ++ 11. Трассировка стека во время тупика выглядит так:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007fb4049e250d in __lll_lock_wait () from /lib64/libpthread.so.0
Id Target Id Frame
* 1 Thread 0x7fb40533b740 (LWP 26259) "i-foca" 0x00007fb4049e250d in __lll_lock_wait () from /lib64/libpthread.so.0
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007fb4049e250d in __lll_lock_wait () from /lib64/libpthread.so.0
Thread 1 (Thread 0x7fb40533b740 (LWP 26259)):
#0 0x00007fb4049e250d in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007fb4049dde76 in _L_lock_941 () from /lib64/libpthread.so.0
#2 0x00007fb4049ddd6f in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007fb40403a0af in dl_iterate_phdr () from /lib64/libc.so.6
#4 0x00007fb3eb7f3bbf in _Unwind_Find_FDE () from /lib64/libgcc_s.so.1
#5 0x00007fb3eb7f0d2c in ?? () from /lib64/libgcc_s.so.1
#6 0x00007fb3eb7f16ed in ?? () from /lib64/libgcc_s.so.1
#7 0x00007fb3eb7f1b7e in _Unwind_RaiseException () from /lib64/libgcc_s.so.1
#8 0x00007fb3eba56986 in __cxa_throw () from /lib64/libstdc++.so.6
#9 0x00007fb3e7b3dd39 in <my library>
Код, вызывающий тупик, в основном throw NameError(...);
, то есть стандартная конструкция C ++, которая должна быть потокобезопасной. Тем не менее, код тем не менее заходит в тупик, пытаясь получить мьютекс в GLIB C s dl_iterate_phdr()
. О среде известна следующая дополнительная информация:
- Несмотря на то, что моя библиотека может порождать несколько потоков, во время инцидента она работала в однопоточном режиме, о чем свидетельствует трассировка стека;
- Программа, в которой используется моя библиотека, выполняет обширное разветвление без выполнения;
- Моя библиотека использует обработчик at-fork, чтобы дезинфицировать все свои мьютексы / потоки при возникновении вилки (однако я не контролирую над мьютексами в стандартных библиотеках). В частности, вилка не может произойти, пока генерируется исключение.
Я до сих пор не понимаю, как могла возникнуть эта взаимоблокировка.
Я рассматриваю следующий сценарий ios, но не уверен, какой из них возможен, а какой нет:
Имеется несколько дочерних процессов. Один из них пытается вызвать исключение и вылетает. Если каким-то образом мьютекс, который использует GLIB C, разделяется между дочерними процессами, и один из дочерних процессов блокирует его, но затем не может разблокировать из-за cra sh. Возможно ли такое совместное использование мьютекса?
Другая библиотека, о которой я не знаю, также использует несколько потоков, и вилка происходит, когда эта библиотека выдает исключение в своем коде, который оставляет мьютекс исключения в дочернем процессе в заблокированном состоянии. Тогда моей библиотеке просто не повезло, чтобы попасть в эту ловушку.
Любой другой сценарий?