Сбой в Windows 10 при вызове LeaveCriticalSectionC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Сбой в Windows 10 при вызове LeaveCriticalSection

Сообщение Anonymous »

У меня возникла проблема с синхронизацией потоков и критических разделов в Windows 10.

В этом случае приложение выйдет из строя:
  • Приложение имеет два потока.
  • Поток 1 вызывает EnterCriticalSection с объектом m_CS
  • Поток 2 затем пытается для входа в тот же критический раздел
  • Поток 1 завершает поток 2 с помощью TerminateThread
  • Поток 1 вызывает LeaveCriticalSection
В предыдущих версиях Windows, которые мне удалось протестировать (7, 8, 8.1), это работает правильно. Поток 2 завершается, а поток 1 без исключения покидает критический раздел.

В Windows 10, когда поток 1 покидает критический раздел, происходит сбой приложения с нарушением прав доступа. Это происходит только тогда, когда другой поток был завершен во время ожидания EnterCriticalThread.

Если посмотреть на трассировку стека, то это выглядит так (последний кадр вверху):

Код: Выделить всё

RtlpWakeByAddress
RtlpUnWaitCriticalSection
RtlLeaveCriticalSection
Я потратил так много времени на устранение этой проблемы. В моем случае с m_CS все в порядке при вызове LeaveCriticalSection. Я отладил и потратил некоторое время на анализ дизассемблированного кода функций ntdll.dll. Похоже, что объект где-то повреждается во время выполнения RtlpUnWaitCriticalSection, а затем передается в RtlpWakeByAddress при возникновении сбоя. По сути, ntdll.dll могла изменять свойства объекта CRITICAL_SECTION, такие как количество блокировок в RtlLeaveCriticalSection.

В Интернете я не нашел ни ответа на этот вопрос, ни утверждения, что изменилось в Windows 10. Только ветка на Reddit и около 1800 отчетов о сбоях для Mozilla Firefox с тем же стеком вызовов за последний месяц. Я связался с автором сообщения на Reddit, и он пока не смог это исправить.

Итак, кто-нибудь сталкивался с этой проблемой и, возможно, у него есть решение или совет. ? В качестве решения сейчас я вижу только переосмысление использования WinAPI TerminateThread и старание избегать его, насколько это возможно. Вероятно, это еще один способ провести рефакторинг кода и подумать об архитектуре приложения.

Любой ответ приветствуется.
Заранее спасибо

Подробнее здесь: https://stackoverflow.com/questions/396 ... calsection
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»