全局覆盖visual c ++中的malloc

我试图找到一种在visual c ++(2005)中全局覆盖malloc和相关函数的方法。 我的设置是一个带有静态链接运行时库的DLL,它包含我自己的c ++代码,外部c ++和c代码。 我想要完成的是允许dll的用户设置他们自己的内存分配函数的实现。

我无法使用的解决方案:

  • 全局覆盖new和delete,我的代码库中有很多外部C库,这意味着它不会捕获很多分配。
  • 将malloc定义为不同的符号。 这将迫使我将此定义推送到所有使用的外部库的构建设置中,我真的想避免这种情况。

我不关心的事情

  • 如果任何外部库以某种其他方式分配内存(HeapAlloc,内存映射文件或它们提出的任何内容),我接受通过重写malloc将无法正确跟踪它。

我能提出的最合理的解决方案是以某种方式干扰链接过程并确保我自己的malloc被链接而不是标准的,最好是我希望能够使用旧的malloc函数作为默认值。

在google perf-tools中 ,似乎他们在运行时手动修补函数的代码,以允许在调用原始函数之前调用钩子函数。 这真的是最好的方法吗?

我也渴望为此找到一个简洁的解决方案。 我们为多个平台编译,所以在非windows窗口我们可以使用的东西 – 愉快地包裹。 我们只需要创建替换function,它们都可以正常运行而不会出现任何错误或黑客攻击。

在窗口方面,我们覆盖malloc调用,但是然后使用/FORCE:MULTIPLE来处理链接器错误。 它工作,记忆function被调用,一切都被跟踪,但感觉就像一个黑客。

来自MSDN:

A file created with this option may not run as expected. The linker will not link incrementally when the /FORCE option is specified.

它不仅感觉像是黑客,还会杀死编辑并继续进行。

/FORCE:MULTIPLE选项可能会解决您的问题,但我并不认为这是一种治疗方法,我仍然试图找到它。

MSDN / FORCE文档

:D

以下在Linux上也是如此,但也可能适用于Win的Visual C ++。

  1. Mallocfunction由系统库glibc提供。 默认情况下,可执行文件与其相关联。

  2. 运行程序时,动态加载程序会注意到可执行文件需要malloc函数并查找提供它的第一个库。

  3. 由于glibc(默认情况下)是该列表中的最后一个,因此找到的库可能不是glibc。

除非你将glibc静态链接到可执行文件中,否则显而易见的解决方案是将可执行文件链接到提供自己的malloc的库,并确保它确实覆盖了系统的。

您可以使用Microsoft的Detours (支付商业费用)或重写您使用的dll的导入表。

我使用的解决方案是从源代码重建Visual C ++ C运行时库(crt)。

它可以在这个文件夹中找到:

C:\ Program Files \ Microsoft Visual Studio 9.0 \ VC \ crt

确保启动Visual Studio命令提示符以构建它。 运行nmake足以启动它构建,尽管您可能想要确定要构建的目标,这意味着您必须了解makefile。

可能需要花费精力来理解如何构建crt,但是一旦你构建了crt,就可以将自己的代码添加到malloc,free和realloc等。

不幸的是,我听说有传言说我们无法从Visual Studio 2010开始从源代码构建crt。

不幸的是,我对微软链接器的了解还不够。 但ld有’–wrap’,你可以用它来做任何事情,比如malloc或free或其他任何东西(我这样做)。

所有对malloc的调用都将被重定向到你已经实现的名为__wrap_malloc的函数,然后你可以使用__real_malloc调用真正的malloc。 这样做的好处是可以捕获外部库中使用的任何malloc。 我确定Microsoft链接器可能具有类似的function。

您可以使用lib中的lib.exe删除这些.obj文件。 我不能更具体,但我记得在我从源头构建Chromium时这样做。

使用LIB工具从运行时库中删除包含内存管理function的所有.obj文件,然后使用IDE中的“忽略默认库”选项并手动指定“您的”运行时库。 然后编译; 你应该得到一些关于undefined mallocfree等的链接器错误。 这是你进来的地方!

(如果你使用它们,你可能也想做类似于C ++库的事情,虽然我认为默认的operator new的调用malloc所以你可能很乐意直接去。)

Visual Studio安装附带运行时源代码(在Visual Studio安装文件夹中查看vc/crt/src ),因此查找完整的内存管理function集非常简单。 我手边没有确切的细节(以前的雇主……),但我记得,即使有比我预期更多的内存分配function,也只需要大约半天的时间来整理。