全局覆盖visual c ++中的malloc

时间:2009-08-22 13:49:08

标签: c++ c malloc override

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

我无法使用的解决方案:

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

我不关心的事情

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

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

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

7 个答案:

答案 0 :(得分:7)

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

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

来自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 Documentation

:D

答案 1 :(得分:5)

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

  1. Malloc功能由系统库glibc提供。默认情况下,可执行文件与其链接。

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

我使用的解决方案是从源代码重建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。

答案 4 :(得分:1)

不幸的是,我对微软链接器的了解不够。但ld有'--wrap'可以用于任何类似malloc或free或其他任何东西(我这样做)。

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

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

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