在 Visual C++ 中全局覆盖 malloc

发布于 2024-08-02 04:11:32 字数 670 浏览 6 评论 0原文

我正在尝试找出一种在 Visual C++ (2005) 中全局重写 malloc 和相关函数的方法。 我的设置是一个带有静态链接运行时库的 dll,其中包含我自己的 C++ 代码、外部 C++ 和 C 代码。 我想要完成的是允许 dll 用户设置自己的内存分配函数实现。

我无法使用的解决方案:

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

我不关心的事情:

  • 如果任何外部库以其他方式分配内存(HeapAlloc、内存映射文件或他们提出的任何内容),我承认这不会通过覆盖 malloc 来正确跟踪。

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

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

I'm trying to figure out a way to globally override malloc and related functions in visual c++ (2005). My setup is a dll with statically linked runtime library that consists of both my own c++ code, external c++ and c code. What I want to accomplish is to allow a user of the dll to set their own implementations of the memory allocation functions.

Solutions that I can't use:

  • Overriding new and delete globally, there is lots of external C libraries in my code base which means this won't capture many allocations.
  • # defining malloc to a different symbol. This would force me to push this define into the build settings of all external libraries used and I really want to avoid this.

Things I don't care about:

  • If any of the external libraries are allocating memory in some other way (HeapAlloc, memory mapped files or whatever they come up with), I accept that this won't be tracked properly by overriding malloc.

The most reasonable solution I can come up with is somehow interfering with the link process and making sure my own malloc is being linked instead of the standard ones, preferably I'd like to be able to use the old malloc functions as default.

In google perf-tools it seems like they patch the code of the functions manually at runtime to allow a hook function to be called before calling the original function. Is this really the best way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

木格 2024-08-09 04:11:32

我也渴望为此找到一个巧妙的解决方案。 我们针对多个平台进行编译,因此在非 Windows 方面我们可以愉快地使用 --wrap。 我们只需要创建替换函数,它就可以正常工作,没有任何错误或黑客攻击。

在 Windows 方面,我们覆盖 malloc 调用,但随后使用 /FORCE:MULTIPLE 来处理链接器错误。 它可以工作,内存函数被调用,一切都被跟踪,但感觉就像是黑客攻击。

来自 MSDN:

使用此选项创建的文件可能无法按预期运行。 当指定 /FORCE 选项时,链接器不会增量链接。

这不仅感觉像是黑客攻击,而且还会终止进程中的编辑和继续。

/FORCE:MULTIPLE 选项可能会解决您的问题,但我并不是建议将其作为治疗方法,我仍在尝试找到它。

MSDN /FORCE 文档

:D

I'm keen to find a neat solution for this too. We compile for multiple platforms, so on the non-windows side of things we can use --wrap happily. We just have to create the replacement functions and it all works without any errors or hacks.

On the windows side of things, we override the malloc calls, but then use /FORCE:MULTIPLE to deal with the linker errors. It works, the memory functions are called and everything is tracked, but it feels like a hack.

From MSDN:

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

Not only does it feel like a hack, it kills edit and continue in the process.

The /FORCE:MULTIPLE option might fix your problems, but I'm not suggesting it as a cure, I'm still trying to find that.

MSDN /FORCE Documentation

: D

木有鱼丸 2024-08-09 04:11:32

以下内容在 Linux 上正确,但也可能适用于 Win 的 Visual C++。

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

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

    当程序运行时

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

    由于

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

The following is true on Linux, but may be applicable to Win's visual C++ as well.

  1. Malloc funciton is provided by system library glibc. The executable is by default linked against it.

  2. When the program is run, the dynamic loader notices that executable needs malloc function and looks for the first library that provides it.

  3. As glibc is (by default) the last in that list, the library found may not be glibc.

Unless you have statically linked glibc into the executable, the obvious solution is to link the executable against the library that provides your own malloc, and make sure that it does override the system's one.

放低过去 2024-08-09 04:11:32

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

You can use Detours from Microsoft (pay for commercial) or rewrite the import tables for the dlls you use.

初雪 2024-08-09 04:11:32

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

可以在以下文件夹中找到它:

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

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

理解如何构建 crt 可能需要花费一些功夫,但是一旦构建了它,您就可以将自己的代码添加到 malloc、free 和 realloc 等中。

不幸的是,我听到一个传言说我们将无法构建从 Visual Studio 2010 开始,来自源代码的 crt。

A solution I have used is to rebuild the Visual C++ C runtime library (crt) from source code.

It can be found here in this folder:

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

Make sure you start up the Visual Studio command prompt to build it. Running nmake is enough to start it building although you might want to work out which target to build and this means you will have to understand the makefile.

It may take an effort to understand how to build the crt, but once you have it building you can add your own code into malloc, free and realloc, etc.

Unfortunately I have heard a rumour that we won't be able to build the crt from source code starting with Visual Studio 2010.

诠释孤独 2024-08-09 04:11:32

您可以使用 lib.exe 从 lib 中删除这些 .obj 文件。我不能说得更具体,但我确实记得当我从源代码构建 Chromium 时这样做过。

You can remove those .obj files with lib.exe from lib. I can't be more specific but I do remember doing it when I was building Chromium from source.

尤怨 2024-08-09 04:11:32

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

(如果您使用 C++ 库,您可能还想做一些类似于 C++ 库的事情,尽管我认为默认的 operator new 调用 malloc 所以您可能会更好立即进行。)

Visual Studio 安装附带了运行时源代码(查看 Visual Studio 安装文件夹中的 vc/crt/src),因此查找全套内存管理函数相当简单。我没有确切的细节(以前的雇主......),但据我记得,尽管内存分配函数比我预期的要多,但只花了大约半天的时间来整理。

Remove all of the .obj files that contain memory management functions from the runtime libraries using the LIB tool, then use the "Ignore default libraries" option in the IDE and manually specify "your" runtime library instead. Then compile; you should get a few linker errors about undefined malloc and free and so on. This is where you come in!

(You'll probably also want to do something similar to the C++ libraries if you use them, though I think the default operator news call malloc so you might be good to go straight away.)

The Visual Studio install comes with the runtime source code (look in vc/crt/src in your Visual Studio install folder), so finding the full set of memory management functions is fairly straightforward. I don't have exact details to hand (previous employer...) but as I recall, it only took about half a day to sort out even though there were rather more memory allocation functions than I expected.

向日葵 2024-08-09 04:11:32

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

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

Unfortunately I don't know enough about the microsoft linker. But ld has '--wrap' which you can use for anything like malloc or free or anything else (I do this).

all calls to malloc will be redirected to a function called __wrap_malloc which you have implemented, you can then call real malloc with __real_malloc. This has the benefit of capturing any mallocs used in external libraries too. I'm sure the Microsoft linker might have a similar function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文