前言
最近项目里总是遇到 dll
加载不上的问题,原因各种各样。今天先总结一个虽然不是项目中实际遇到的问题,但是却非常经典的问题。其它几种问题,后续慢慢总结。
示例代码包含一个 exe
工程,两个 dll
工程。exe
会加载两个 dll
并调用它们的导出函数(GetCallCount
),结果只有一个 dll
的导出函数被成功调用。会是什么原因呢?
现象
运行效果如下图:
通过 dumpbin
已经确认两个 dll
都有名为 GetCallCount
的函数。但是只有一个调用成功了,另外一个却调用失败。
使用 process explorer
观察 dll
加载情况,发现只加载了一个 dll
,没发现另外一个 dll
。
对于这个问题,如果我们使用 procmon
观察整个加载过程,看到的都是 Success
。如下图:
说明,加载正常,在本地找到了这个文件,并正确的映射到内存空间中了。但为什么在进程中观察不到这个 dll
呢?是时候上调试器了。
上调试器
直接在 vs
中按 F5
启动,果然中断到 vs
中了。
从上图右侧部分,我们可以看到完整的调用栈。
这里简单介绍下相关代码。在 GlobalVariableInitializeOrder.cpp
的第 15
行调用了 HMODULE hDll2 = LoadLibraryA("GlobalVariableInitializeOrderDll2.dll");
加载对应的模块。
Common\Test2.cpp
的第 10
行定义了全局变量 CTest2 g_t2;
,问题就出在这个全局变量的初始化代码中。
从上图左侧部分,我们可以得知错误代码是 0xc0000005
,内存访问异常。访问的地址是 0x00000004
,对应的指令位置是 0x001EA6DB
。