2 копии DLL в одном процессе
От: TheRawGod  
Дата: 20.12.07 13:08
Оценка: 10 (2)
Коллеги,

сразу хочу отметить, что вопрос сюда пришел постепенно, по пути msdn -> microsoft.public.vc.atl -> wasm -> rsdn. К сожалению, ответ нигде получить не получилось, поэтому дублирую здесь, прошу прощения у тех, если кто его читает не в первый раз.

Ситуация следующая: в процессе работы над проектом мы натолкнулись на то, что при определенных условиях нам удается загрузить одну и ту же dll в один процесс 2 раза. Фактический mapping type в обоих случаях Image, пути загрузки — идентичны. Чтобы показать проблему был сделан простенький пример (solution из 3-х native win32 C++ проектов для Visual Studio 2005).

В нем мы грузим проблемную длл вначале с помощью SxS COM, создавая объект, живущий в ней, а воторой раз — как статически прилинкованную к загружаемой через LoadLibrary длл (т.е. делаем LoadLibrary "промежуточной" длл, в таблице импорта которой находится "проблемная" первоначальная дублирующаяся длл (та, в которой живут созданные раньше через SxS com объекты)). Порядок загрузки изображен тут.

В результате смотрим, например, Process Explorer'ом и видим 2 копии одной и той же длл.

Меня бы может и устроил ответ, что, типа, в одном случае у нас com грузит, а в другом — LoadLibrary, да и то опосредованно через таблицу импорта и все такое (хотя это, имхо, бред, какая разница как оно грузится, если образ один и тот-же, да и поискать в ctnb если, то везде говорят, что "dll can't be loaded twice" с различным вариациями), если бы не еще несколько НО с нашей точки зрения:
1. Если в указанном примере использовать обычный com, а не SxS, то копия длл оказывается одна.
2. Если изменить порядок загрузки и вначале грузить через LoadLibrary, а потом создавать объект через SxS com — то опять-же, копия одна.

И пускай уже, пункт 1 я готов принять как некий by design, но вот пункт 2 ставит большой знак вопроса. Какими бы ни были разными механизмы загрузки, но порядок их использования не должен влиять на конечный результат.

Более того, если поставить бряки в DllMain дублирующейся длл, то студия дуреет: при первоначальной загрузке через SxS все красиво брякается, а вот при повторной непонятной загрузке студийные бряки не срабатывают. Если поусердствовать и вручную всунуть int3, то это приводит студию в шок и она показывает в стеке вызовов полную ерунду + асм код вместо исходников. Т.е. она видит, что длл загружена по одному базовому адресу и никак не хочет принимать тот факт, что та же длл есть и еще по другому адресу в том-же процессе.

В результате мы подозреваем баг в загрузчике WinXP SP2 / Vista (воспроизводится аналогично), неким образом очевидно связанный с Side by Side COM.

Очень буду вам благодарен за опровержение и любые иные аргументированные соображения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.