Тупик при выдаче исключения в C ++ - PullRequest
0 голосов
/ 05 мая 2020

Я изучаю отчет о тупике, который произошел в моей библиотеке, которая обычно многопоточна и написана на 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, но не уверен, какой из них возможен, а какой нет:

  1. Имеется несколько дочерних процессов. Один из них пытается вызвать исключение и вылетает. Если каким-то образом мьютекс, который использует GLIB C, разделяется между дочерними процессами, и один из дочерних процессов блокирует его, но затем не может разблокировать из-за cra sh. Возможно ли такое совместное использование мьютекса?

  2. Другая библиотека, о которой я не знаю, также использует несколько потоков, и вилка происходит, когда эта библиотека выдает исключение в своем коде, который оставляет мьютекс исключения в дочернем процессе в заблокированном состоянии. Тогда моей библиотеке просто не повезло, чтобы попасть в эту ловушку.

  3. Любой другой сценарий?

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