Как GetStringType вызывает тупик в Dll Main? - PullRequest
0 голосов
/ 20 февраля 2020

Я смотрю на приложение, которое висит на Server 2016, но запускает find на Server 2008 R2. Я проследил это до зависания, вызванного взаимоблокировкой при загрузке определенной DLL. Анализируя DLL (у меня нет исходного кода), я вижу, что она нарушает директиву здесь

  • Вызов GetStringTypeA, GetStringTypeEx или GetStringTypeW (прямо или косвенно) , Это может вызвать тупик или взлом sh

В частности, он вызывает GetStringTypeW из DllMain.

Я пытаюсь понять, как эта функция может вызвать взаимные блокировки в DllMain.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

При вызове функции из DllMain, которая будет (прямо или косвенно) пытаться загрузить другой модуль, происходит тупик.

Загрузка модуля сериализована. Система использует блокировку, чтобы гарантировать, что в любой момент времени вводится не более одной точки входа DLL. Если вы звоните LoadLibrary (прямо или косвенно) из вашей точки входа DLL, вы держите блокировку загрузчика. LoadLibrary попытается получить блокировку загрузчика до вызова точки входа модуля. Поэтому, пока ваш код ожидает возврата LoadLibrary, LoadLibrary ожидает блокировки, которую вы держите. Это тупик.

Это, вероятно, причина, по которой вызов GetStringType из DllMain тупиков. Без доступа к исходному коду я не могу это проверить, хотя. Вы можете найти доказательства, включив оснастки загрузчика .

0 голосов
/ 20 февраля 2020

Ваша функция DllMain работает внутри блокировки загрузчика, один из немногих случаев, когда ОС позволяет вам запускать код, пока удерживается одна из его внутренних блокировок. Это означает, что вы должны быть особенно осторожны, чтобы не нарушать иерархию блокировок в вашей DllMain; в противном случае вы просите тупик. (См. « Еще одна причина не делать ничего страшного в DllMain: непреднамеренная тупик »)

DllMain вызывается, пока удерживается блокировка загрузчика, поэтому если GetStringType получает блокировку загрузчика, появляется тупик.

Существенные ограничения накладываются на функции, которые можно вызывать в DllMain. Таким образом, DllMain предназначен для выполнения минимальных задач инициализации с использованием небольшого подмножества Microsoft® Windows® API. Вы не можете вызвать любую функцию в DllMain, которая прямо или косвенно пытается получить блокировку загрузчика. В противном случае вы представите вероятность того, что ваше приложение заблокируется или выйдет из строя.

Мы можем ' см. исходный код функции GetStringType. Рекомендуется следовать рекомендациям Dynami c -Link Library .

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