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 损坏?

VS2015 MFC 修改应用程窗口大小 标题

0xc0000374 未附加调试时 Cli/Cpp 代码中的堆损坏

如何初始化堆,以便常规 MFC dll 中的静态构造函数可以使用它?

Visual Studio 2008. MFC 事件向导损坏