Что может блокировать getmodulefilename?

У нас есть многопоточное приложение. Один из рабочих потоков вызывает GetModuleFilename для ведения журнала, и мы видели тупик, когда рабочие потоки удерживали блокировку перед вызовом GetModuleFilename, который блокируется навсегда.

Мы можем и удалили вызов GetModuleFilename изнутри этой блокировки, но все еще очень заинтересованы в том, как именно происходит взаимоблокировка.

Чтение в Интернете: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx

похоже, что GetModuleFilename получит блокировку загрузчика, которая казалась довольно хорошим кандидатом в тупик.

Но, как правило, потоки внутри блокировки загрузчика не будут выполнять какой-либо наш собственный код, кроме как в dllmain по ссылке выше.

dll_thread_attach или detach может быть вызван в блокировке загрузчика и на другом рабочем потоке, который создается или уничтожается, но я не вижу способа, которым это попыталось бы получить блокировку, которую мы используем.

Также возможно, что основной поток пытается получить блокировку, которую удерживает поток GetModuleFilename, а третий поток удерживает блокировку загрузчика и выполняет sendmessage или что-то в этом роде в основном потоке? Здесь также я не нашел никаких обстоятельств, при которых это произойдет.

один из других потоков, который я подозреваю, это тот, который использует объект com. В начале поток вызывает coinitialize, поэтому он должен находиться в однопоточной квартире. Есть ли здесь возможности взаимодействия с loaderlock?

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

Благодарю.

2 ответа

Решение

Что ж, оказывается, проблема, которую я описал, была просто симптомом другой проблемы в библиотеке, которую мы использовали. Библиотека, очевидно, использовала некоторые API Wininet в двух разных потоках, один из которых был в dllmain и внутри блокировки загрузчика. Эти два потока заблокированы, что впоследствии заблокировало наш поток, который называется GetModuleFileName.

Это примерно столько, сколько я знаю на данный момент, но я обновлю это, как только мы получим более подробную информацию от продавца библиотеки.

Просто несколько случайных идей:

  • Если есть код C++ (не только C), возможно, что конструкторы статически размещенных объектов в DLL также выполняются, пока система удерживает блокировку загрузки. Разве вы не используете свой замок в конструкторе / деструкторе такого объекта?

  • Возможно, ошибка может быть там, несмотря на вашу блокировку, и использование блокировки может на самом деле просто "показать" гонку, например, изменив время выполнения действий в каком-либо потоке. DllMain() и темы могут быть хитрыми. См. http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

Другие вопросы по тегам