Базовый адрес Dll

У меня есть небольшое тестовое решение с одним exe и тремя Dll, exe вызывает три Dll по одному. Я установил параметр Build->Advanced->DLL Base Address на 0x41000000, 0x42000000 и 0x43000000 для Dll1.dll, Dll2.dll и Dll3.dll соответственно. Я бегал

ngen install ConsoleApplication1.exe

и это успешно ngen'd приложение вместе с тремя Dll. Я действительно не хотел запускать exe, но пока это единственный способ получить какие-либо результаты вообще.

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

Я веду логи:

   Dll1       Dll2       Dll3
0x40140000 0x411D0000 0x42810000 
0x40580000 0x41EB0000 0x426B0000 
0x40190000 0x41FB0000 0x42380000 
0x40F30000 0x41FD0000 0x42050000 
0x409B0000 0x41BF0000 0x42910000 
0x408E0000 0x41860000 0x42050000 
0x40B50000 0x41280000 0x42A80000

Обратите внимание, что первые две цифры адреса остаются согласованными для всех трех библиотек Dll во всех запусках.

Мой актуальный вопрос: это показатель успеха? Я немного сбит с толку, потому что я думал, что Dlls будут сидеть точно в 0x41000000, 0x42000000 и 0x43000000. Результаты показывают, что они торчат вокруг этой области, но никогда не сидят там, где я их просил. Насколько я понимаю, вы хотите, чтобы Dll загружались именно по адресу, который вы их просили, чтобы им не пришлось проходить дорогостоящую операцию перебазирования (которая очень дорогая, когда ваши Dll были ngen'd). Но разве это не то, что происходит? Конечно, мои Dll торчат в определенной области, но они не сидят именно там, где я их просил, так что, конечно, дорогостоящая операция перебазировки выполняется каждый раз? Это именно то, чего я хотел избежать.

Примечание: меня не интересуют аргументы за / против перебазирования и ngen. Я просто хочу знать, что происходит и как заставить это работать.

Ура ТАК!

2 ответа

Решение

Может быть ASLR (рандомизация расположения адресов) - проверьте ссылки с http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/bac7e300-f3df-4087-9c4b-847880d625ad

Не ограничивает ли инструмент NGEN указание базового адреса для двоичного образа, который он создает для сборки. Afaik, вы должны скомпилировать "предпочтительный базовый адрес" в саму сборку. http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

Редактировать *

Однако, если загрузчик не может разместить модуль по нужному адресу (поскольку он перекрывается с другим модулем или фрагментом данных, уже загруженным или выделенным), модуль перезагружается, то есть он загружается по другому адресу. Это означает, что все адреса в исполняемом образе должны быть исправлены.

Также, глядя на Интернет, многие разработчики, похоже, хотят эту функцию, но проблема заключается в резервировании базовых адресов, которые не конфликтуют с другими сборками разработчиков. Какие еще библиотеки DLL находятся по адресам, по которым вы ожидали, что у вас будет?

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