2

我有一个带有一个 exe 和三个 Dll 的小型测试解决方案,该 exe 分别调用三个 Dll 一次。我已将Dll1.dll、Dll2.dll 和 Dll3.dll 的 Build- >Advanced->DLL Base Address设置分别设置为 0x41000000、0x42000000 和 0x43000000。我跑了

ngen install ConsoleApplication1.exe

这已经成功地将应用程序与三个 Dll 一起生成。我真的不想生成 exe,但到目前为止,这是产生任何结果的唯一方法。

在运行时,我使用 VMMap 监视虚拟地址空间,它显示 ngen 的 Dll 位于一致的虚拟内存范围内,但是它们仍在该范围内跳跃,每次我运行时加载的地址都略有不同他们。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 保持一致。

我的实际问题是:这是成功的指标吗?我有点困惑,因为我认为 Dll 将恰好位于 0x41000000、0x42000000 和 0x43000000。结果表明他们在那个区域徘徊,但从未真正坐在我让他们坐的地方。我的理解是,您希望将 Dll 准确地加载到您要求它们加载的地址,这样它们就不必进行昂贵的变基操作(当您的 Dll 被 ngen'd 时,这非常昂贵)但是,这不正是正在发生的事情吗?当然,我的 Dll 在某个区域徘徊,但它们并没有完全坐在我要求它们坐的位置,所以每次运行时肯定会执行昂贵的变基操作吗?这正是我想要避免的。

注意:我对支持/反对 rebase 和 ngen 的论点不感兴趣。我只想知道发生了什么以及如何让它工作。

干杯!

4

2 回答 2

3

可能是 ASLR(地址空间布局随机化) - 查看来自http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/bac7e300-f3df-4087-9c4b-847880d625ad的链接

于 2011-09-13T00:17:57.317 回答
0

NGEN 工具不限制为它为程序集制作的二进制图像指定基地址。Afaik 您必须将“首选基址”编译到程序集本身中。http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

编辑 *

但是,如果加载器无法将模块放置在所需的地址(因为它与另一个模块或已加载或分配的数据重叠),则模块将被重新定位,这意味着它被加载到其他地址。这意味着需要修复可执行映像中的所有地址。

还看看互联网,似乎许多开发人员希望使用此功能,但问题是保留与其他开发人员程序集不冲突的基地址。在您期望的地址上还有哪些其他 DLL?

于 2011-09-13T00:24:01.043 回答