MFC 应用程序中的“仅 Vista”堆损坏
Posted
技术标签:
【中文标题】MFC 应用程序中的“仅 Vista”堆损坏【英文标题】:"Vista-only" heap corruption in a MFC application 【发布时间】:2011-09-27 04:49:00 【问题描述】:Ours 是一个 MFC 应用程序,它链接到一个 win32 DLL。当应用程序调用这个 DLL 函数时,参数“buffer”在进入函数堆栈后变成了一个“Bad Pointer”。这会导致应用程序崩溃。
static MyClass* Instance(string& buffer);
我将参数类型更改为“char *”,但它只会将崩溃推送到函数中的下一条语句。如何检测这种堆损坏?
一些提示
即使我从应用程序的一开始就调用此 DLL 函数(CWinApp 构造函数),此崩溃也是可重现的。这种内存损坏是否是由加载资源、清单等引起的? 在 Vista 和 Win7 中会发生崩溃,但在 XP 中不会发生。 这两个项目最近都从 Visual Studio 2002 迁移到 VS2008。调用函数的代码
CString data = "some string";
string str = data.GetBuffer();
data.ReleaseBuffer();
MyClass *obj = MyClass::Instance(str);
【问题讨论】:
目标操作系统位版本是多少? 32 位还是 64 位? 它是一个 32 位应用程序 显示调用实例的邮政编码。 exe和dll是否都使用相同类型的共享crt(多线程dll/单线程dll)? 发布调用代码。 exe和dll都使用多线程dll的共享CRT 在Instance的调用过程中,字符串分配的内存是否真的发生了变化?查看内存窗口中的字符串内容 - 不要依赖快速观察窗口来获取 str。请注意,您应该能够将数据分配给 str,例如“str = (LPCTSTR) data;”然后可以删除 ReleaseBuffer 调用。 【参考方案1】:有两个错误:
几个自定义构建的 C++ 文件未使用 MD 开关编译。我们必须在自定义构建脚本中添加 -MD 以使 CRT 与其他对象保持一致。
LIBCMT.LIB 和 MSVCRT.LIB 之间存在 LNK2005 冲突,否则由于 /FORCE 开关而被忽略。我们通过删除 Linker->Input
中的 LIBCMT.LIB 解决了这些冲突感谢大家的帮助。
【讨论】:
【参考方案2】:我猜这是 calling conventions 的错误用法或 CRT 不匹配(我使用调用约定)。
尝试使用相同的函数签名(不执行任何操作)构建存根 DLL,并使其与您的 MFC 应用程序一起使用。
这是example...
HTH
【讨论】:
以上是关于MFC 应用程序中的“仅 Vista”堆损坏的主要内容,如果未能解决你的问题,请参考以下文章
在 Close() 检测到 MFC CRecordset 堆损坏
MFC 程序挂起:在 Vista 上更新 KB3059317 后 Comctl32.dll 损坏?
0xc0000374 未附加调试时 Cli/Cpp 代码中的堆损坏