调试实战 —— dll 加载失败之 Debug Release争锋篇

本文通过一个实例分析了DLL加载失败的原因,发现是由于Debug和Release模式下基类不同,导致内存结构差异,进而使得全局变量初始化时发生异常,最终造成DLL加载异常。通过Windbg调试,作者揭示了问题的根本所在,并提醒读者避免混用Debug和Release模式的DLL。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缘起

最近,项目里遇到一个 dll 加载不上的问题。实际项目比较复杂,但是解决后,又是这么的简单,合情合理。本文是我使用示例工程模拟的,实际项目中另有玄机,但问题的本质是一样的。本文从行文上与 《调试实战 —— dll 加载失败之全局变量初始化篇》  非常相似,示例代码也非常相似(原谅我比较懒),感兴趣的小伙伴儿可以对比来读。

背景介绍

示例代码中一共有四个工程,一个 exe,三个 dll。其中,Base.vcxproj 是封装了公共接口的工程,会生成 Base.dllExtension1.vcxprojExtension2.vcxproj 非常相似,会分别生成 Extension1.dllExtension2.dllMixConfiguration.vcxproj 会生成 MixConfiguration.exe ,该 exe 会加载 Extension1.dllExtension2.dll ,并调用它们的导出函数(象征性的调用)。程序运行起来后,发现只有一个 dll 的功能正常,另外一个 dll 的功能执行不正常。如下图:

已经使用 dumpbin 确认两个 dll 都有名为 GetCallCount 的函数。但是只有一个调用成功了,另外一个却调用失败。

使用 process explorer 观察 dll 加载情况,发现只加载了一个 dll,没发现另外一个 dll

与上一个问题一样,如果我们用 procmon 观察整个加载过程,看到的都是 Success。这里不截图了。直接上调试器。

上调试器

直接在 vs 中按 F5 启动,果然中断到 vs 中了。

从上图右侧部分,可以看到完整的调用栈。

简单介绍下相关代码。在 MixConfiguration\Entry.cpp 的第 15 行调用了auto hDll2 = LoadLibraryA("Extension2.dll"); 加载对应的模块。在 Extension2\Extension2.cpp 的第 22 行定义了全局变量 CTest2 g_t2,问题就出在这个全局变量的初始化代码中。

从上图左侧部分可知,错误代码是 0xc0000005,内存访问异常。访问的地址是 0x0000000D,对应的指令地址是 008B7F34

从上图可以看出,确实是挂在了 008B7F34 movsx ecx,byte ptr [

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值