Базовый адрес по умолчанию для .exe
, встроенного в Visual Studio, равен 0x00400000.
Базовый адрес по умолчанию для d3dx9_30.dll
и odbcint.dll
(которые оба живут в %windir%\system32
) также равен 0x00400000. Поэтому по умолчанию exe
s, которые ссылаются на любой из этих dll, будут иметь конфликт адресов во время выполнения. ОС автоматически перемещает dll
на другие базовые адреса и исправляет указатели по мере необходимости, и я вижу, что это происходит, когда я подключаю отладчик VS: перемещенный модуль получает наложение восклицательного знака.
Перебазирование системных DLL - это действительно плохая идея, не говоря уже о том, что в пользовательских системах это практически невозможно. Поэтому я решил перебазировать свои exe
s, чтобы предотвратить это столкновение адресов и, таким образом, предотвратить перебазирование во время выполнения.
Если я изменю свой клиентский EXE-файл на другой базовый адрес, чтобы убрать его с пути d3dx9_30.dll
, он будет работать нормально: нет конфликта адресов, нет перемещения, нет исправлений.
Но если я изменю свои серверные EXE-файлы на другой базовый адрес, чтобы убрать их с пути odbcint.dll
, это не сработает.
odbcint.dll
- 0x17000 байт в памяти и предпочитает базовый адрес 0x00400000. Я попытался основать свои EXE-файлы на 0x00420000, а затем на 0x00660000. Тем не менее odbcint.dll
перемещается во время выполнения. Я профилировал с depends.exe
, который показал, что нет другого модуля, пытающегося запросить этот адрес до odbcint.dll
загрузки.
У кого-нибудь есть теория, объясняющая, почему я не могу загрузить odbcint.dll
по его предпочтительному адресу?
Update
:
vadump показывает, что к тому времени, когда я вхожу в main (), память 0x00400000-0x00470000 объявляется как «UNKNOWN_MAPPED». Я не смог найти больше информации о том, что именно это означает. Я предполагаю, что какая-то системная DLL резервирует эту память во время загрузки; мое отладочное фу недостаточно сильное, чтобы понять, что, почему или когда.