【问题标题】:dlmalloc crash on Win7Win7上的dlmalloc崩溃
【发布时间】:2011-05-04 16:59:20
【问题描述】:

一段时间以来,我一直很高兴地将dlmalloc 用于跨平台项目(Windows、Mac OS X、Ubuntu)。然而,最近似乎使用 dlmalloc 会导致 Windows 7 上的退出崩溃。

为了确保它在我的项目中不是愚蠢的,我创建了一个超级最小的测试程序——它除了从 main 返回之外什么都不做。一个版本(“malloctest”)链接到 dlmalloc,而另一个版本(“regulartest”)没有。在 WinXP 上,两者都运行良好。在 Windows 7 上,malloctest 崩溃。您可以看到测试的截屏视频here

我的问题是:为什么会这样?它是 dlmalloc 中的错误吗?还是 Windows 7 中的加载程序发生了变化?有解决办法吗?

fyi,这里是测试代码(test.cpp):

#include <stdio.h>

int main() {
    return 0;
}

这里是nmake makefile:

all: regulartest.exe malloctest.exe

malloctest.exe: malloc.obj test.obj
 link /out:$@ $**

regulartest.exe: test.obj
 link /out:$@ $**

clean:
 del *.exe *.obj

为简洁起见,我不会在这篇文章中包含 dlmalloc 源代码,但您可以获取它 (v2.8.4) here

编辑:查看这些其他相关的 SO 帖子:

【问题讨论】:

    标签: c windows windows-7 malloc


    【解决方案1】:

    看起来像 C 运行时中的错误。在 Windows 7 上使用 Visual Studio 2008,我重现了同样的问题。通过在dlmallocdlfree 中放置断点进行了一些快速调试后,我看到dlfree 被调用了一个从未从dlmalloc 更早返回的地址,然后不久它就遇到了访问冲突。

    幸运的是,C 运行时的源代码与 VS 一起分发,因此我可以看到对 free 的调用来自 _file.c 中的 __endstdio 函数。对应的分配在__initstdio,它正在调用_calloc_crt来分配它的内存。 _calloc_crt 调用_calloc_impl,后者调用HeapAlloc 来获取内存。另一方面,_malloc_crt(在 C 运行时的其他地方使用,例如为环境和argv 分配内存)直接调用malloc,而_free_crt 直接调用free

    因此,对于使用_malloc_crt 分配并使用_free_crt 释放的内存,一切都很好。但是对于使用_calloc_crt 分配并使用_free_crt 释放的内存,就会发生不好的事情。

    我不知道是否支持像这样替换 malloc - 如果支持,那么这是 CRT 的错误。如果没有,我建议研究不同的 C 运行时(例如 MinGW 或 Cygwin GCC)。

    【讨论】:

    • 这不是一个错误,而是解释 为什么 替换 malloc(或任何标准 C 函数)被指定为 未定义行为.
    【解决方案2】:

    在跨平台代码中使用dlmalloc 是矛盾的。替换任何标准 C 函数(尤其是 malloc 和系列)会导致未定义行为。最接近替换malloc 的便携式方法是在源文件上使用搜索和替换(不是#define;这也是UB)来调用(例如)my_malloc 而不是malloc。请注意,内部 C 库函数仍将使用其标准 malloc,因此如果两者发生冲突,事情仍然会崩溃。基本上,试图替换malloc 真的是被误导了。如果您的系统确实有一个损坏的malloc 实现(太慢、太多碎片等),那么您需要以特定于实现的方式进行替换,并禁用所有系统上的替换,除了您仔细考虑过的系统检查您的特定于实现的替换是否正常工作。

    【讨论】:

    • 你听起来好像任何想要覆盖 malloc 的人都是荒谬的。许多项目覆盖 malloc (请参阅我的问题中的新 SO 链接)。通过使用 dlmalloc,我们的项目看到了一些显着的速度提升。可能是我做错了(因为它比 gcc 更难覆盖 msvc 的 malloc),但这是一件完全有效的事情。
    • 合理的说法是:“我测试过某某平台,它的malloc很烂。我还研究了如何在这个平台上替换malloc,我'我这样做是正确的。我已经在我的构建脚本中确保不会在任何系统上尝试替换 malloc,除非我测试它的确切配置。不合理的是:“我将假设系统 malloc 总是很糟糕,而且我的替换通常有效,并且只在我知道有一个“好”malloc 的系统上禁用我的替换。后一种行为有一个名称:它被称为非便携式
    • 我们在 Windows XP 上对其进行了测试,它的 malloc 很糟糕。我研究了如何在该平台上替换 malloc,并且我以正确的方式做到了。现在我们正在研究如何让它在 Windows 7 上运行,因为 Window XP malloc-overriding 技术显然不起作用。您对我的问题(如何使其在 Windows 7 上运行)有实际答案,还是继续争论?
    • 我没有使用 Windows 的经验,所以没有。我所拥有的经验是软件只是假设标准库已损坏并尝试在这里和那里进行替换,然后当我在除了普通 GNU/Linux 之外的任何系统上构建它时无法编译或随机段错误/BSD/视窗。如果我的回答对您没有帮助,我很抱歉,但我认为这对可能正在阅读您的问题的其他人来说是一个合理的建议。
    猜你喜欢
    • 2013-02-15
    • 2012-08-15
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    相关资源
    最近更新 更多