Visual Studio MAP文件中的函数地址不正确

时间:2008-10-08 09:52:38

标签: c++ visual-studio debugging

来自visual studio的我的MAP文件中的函数地址(Rva + Base)与我在调试器中看到的(或者当我手动检查我的堆栈帧时)不匹配。

导致这种情况的原因是什么?

/A.B。

4 个答案:

答案 0 :(得分:2)

可执行文件或DLL中存在问题吗?

如果是DLL,它的首选加载地址是什么?如果这与任何其他DLL发生冲突,那么它将被加载器重新定位,这可能会导致您看到的内容。

作为构建过程的一部分,您应该确保所有DLL都已重新定义(有一个工具来执行此操作),以便它们的地址空间不会发生冲突(这会释放一些页面文件空间以及改善加载时间)。

答案 1 :(得分:1)

除非在链接时指定/ FIXED命令行选项,否则可以重定位exe和dll。我使用以下方法确定真实地址以确定我的exe加载位置,以便我可以计算映射文件的偏移量。

static void KnownFunctionAddress(){}

...

// check an address of a known function
// and compare this to the value read from the map file

intptr_t CheckRelocationOffset(MapFile map)
{
  intptr_t mapAddress = map.PhysicalAddress("?KnownFunctionAddress@@YAXXZ");
  intptr_t realAddress = (intptr_t)KnownFunctionAddress;

  return realAddress-mapAddress;
}

答案 2 :(得分:0)

当您在调试器中并单步执行代码时,是否可以检查代码地址是否在“模块”窗口中看到的范围内?有时,同一段代码可能存在于几个相同/不同名称的模块中。

确定包含代码的“模块”后,使用“模块”窗口中的基址来到达(通过减去)DLL入口点地址。

最后,还有入口跳转表(trampoline)的效果,它是一种可以在编译时或运行时添加的函数调用间接。因此,“入口点”地址可能是烟雾屏幕,并且与功能体的地址不匹配。

(我对DLL结构的理解是有限的,所以我的答案可能不准确。)

答案 3 :(得分:0)

由于某种原因,我无法直接回复Suma的回复,但您也可以执行以下操作:

extern "C" struct IMAGE_DOS_HEADER __ImageBase; // On platforms other than Win32/Win64, this MAY be a different header type...
...
printf_s("base: %p", &__ImageBase);

__ ImageBase由链接器(至少VC ++)定义,并且其地址将为您提供模块的基地址(EXE / DLL),即使它在运行时重新定位。

还有

printf_s("calling module's base: %p\n", GetModuleHandle(NULL));

它可以给你相同的基地址值...但GetModuleHandle还有更多的警告(加上它需要windows.h)所以我建议只坚持__ImageBase。

与其他人提到的一样,您的问题可能与Windows重新定位模块有关。如果模块文件中没有.reloc部分,那么该文件不可重定位,在这种情况下,就像你遇到蹦床或类似rwong建议的那样。