Memory 如何记录mallocs

Memory 如何记录mallocs,memory,memory-management,malloc,Memory,Memory Management,Malloc,这是一个有点假设性的,非常简单,但是 假设一个程序将调用由第三方编写的函数。这些当事人可以被认为是非敌对的,但不能被认为是“有能力的”。每个函数将接受一些参数,具有副作用并返回一个值。它们在不运行时没有状态 目标是确保它们不会导致内存泄漏,方法是记录所有malloc(等等),然后在函数退出后释放所有内容 这可能吗?这实际吗 p、 对我来说,重要的一点是确保没有持续的分配,因此,不这样做就消除内存泄漏的方法对我来说是没有用的。你不能强制他们分配堆栈上的所有内存吗?通过这种方式,可以保证在函数退出后

这是一个有点假设性的,非常简单,但是

假设一个程序将调用由第三方编写的函数。这些当事人可以被认为是非敌对的,但不能被认为是“有能力的”。每个函数将接受一些参数,具有副作用并返回一个值。它们在不运行时没有状态

目标是确保它们不会导致内存泄漏,方法是记录所有malloc(等等),然后在函数退出后释放所有内容

这可能吗?这实际吗


p、 对我来说,重要的一点是确保没有持续的分配,因此,不这样做就消除内存泄漏的方法对我来说是没有用的。

你不能强制他们分配堆栈上的所有内存吗?通过这种方式,可以保证在函数退出后将其释放。

比尝试记录malloc更好的解决方案可能是在调用函数时对其进行沙箱处理,让它们访问固定的内存段,然后在函数运行完毕后释放该段


未经限制、不合格的内存使用可能与恶意代码一样具有破坏性。

您可以在单独的进程中运行第三方函数,并在使用完库后关闭该进程。

首先,您必须为
malloc()
free()
和朋友提供入口点。因为这段代码已经编译好了(对吧?),所以您不能依赖
#define
来重定向

然后,您可以通过将这些例程链接到这些模块,以明显的方式实现它们,并记录它们来自某个模块

最快的方法是根本不记录日志。如果它们使用的内存量是有限制的,为什么不预先分配它们所需的所有“堆”并从中编写分配器呢?然后当它完成后,释放整个“堆”,你就完成了!如果更复杂的话,您可以将这个想法扩展到多个堆

如果您真的需要“登录”而不是创建自己的分配器,这里有一些想法。第一,使用带有指针和内部链接的哈希表。另一种方法是在每个块前面分配额外的空间,并将您自己的结构放在那里,其中包含(比如)一个索引到“日志表”中,然后保留一个日志表项的空闲列表(作为堆栈,所以获取空闲项或将空闲项放回是O(1))。这需要更多内存,但速度应该很快


它实用吗?我认为是的,只要速度可以接受。

因为您担心内存泄漏,并且谈论malloc/free,我假设您使用的是C语言。根据您的问题,我还假设您无法访问第三方库的源代码


我能想到的唯一一件事是在通话前后检查应用程序的内存消耗,记录错误消息(如果它们不同),并说服第三方供应商修复您发现的任何漏洞。

如果您没有指定操作系统或环境,这个答案假设Linux、glibc和C

您可以设置_malloc_hook、_free_hook和_realloc_hook来分别指向将从malloc()、realloc()和free()调用的函数。有一个uu malloc_hook主页显示原型。您可以在这些挂钩中添加跟踪分配,然后返回,让glibc处理内存分配/释放


听起来好像您希望在第三方函数返回时释放任何实时分配。有一些方法可以让gcc使用-finstrument函数在每个函数入口和出口自动插入调用,但我认为这对于您正在尝试的操作来说是不雅观的。在调用其中一个第三方函数后,是否可以在内存跟踪库中调用自己的代码?然后,您可以检查是否存在第三方函数尚未释放的任何分配。

在过去,我用C编写了一个软件库,其中有一个内存管理子系统,该子系统能够记录分配和释放,并手动匹配每个分配和释放。这在尝试查找内存泄漏时有一定的用处,但使用起来既困难又耗时。日志的数量非常多,理解日志需要花费大量的时间

这就是说,如果您的第三方库有大量的分配,那么通过日志记录来跟踪这一情况可能更不切实际。如果您在Windows环境中运行,我建议您使用Purify[1]或BoundsChecker[2]之类的工具来检测第三方库中的泄漏。对该工具的投资应能在节省的时间内收回成本

[1] :净化


(2):BoundsChecker

< P>如果你有多余的钱,那么考虑使用PurieCype跟踪问题。它工作得很好,不需要源代码或重新编译。还有其他更便宜的调试malloc库。电栅栏是我记得的一个名字。也就是说,Denton Gentry提到的调试钩子似乎也很有趣。

如果你太穷,不适合Purify,试试Valgrind。它比6年前要好得多,而且比Purify更容易深入研究。

微软Windows提供(如果需要POSIX,请使用SUA),很可能是当今所有销售操作系统中最先进的heap+(已知使用heap的其他api)基础设施

__malloc()调试钩子和相关的CRT调试接口非常适合有测试源代码的情况,但是它们经常会错过标准库或其他链接代码的分配。这是预期的,因为它们是VisualStudio堆调试基础结构

是一套非常全面和详细的调试功能,多年来一直包含在Windows中。具有源代码和二进制代码用例的高级功能(因为它是OS堆调试基础设施)

它可以记录完整堆栈跟踪(repagin)
@ /usr/lib/tls/libnvidia-tls.so.390.116:[0xf44b795c] + 0x99e5e20 0x49
@ /opt/gcc-7/lib/libstdc++.so.6:(_ZdlPv+0x18)[0xf6a80f78] - 0x99beba0
@ /usr/lib/tls/libnvidia-tls.so.390.116:[0xf44b795c] + 0x9a23ec0 0x10
@ /opt/gcc-7/lib/libstdc++.so.6:(_ZdlPv+0x18)[0xf6a80f78] - 0x9a23ec0
@ /opt/Xorg/lib/video-libs/libGL.so.1:[0xf668ee49] + 0x99c67c0 0x8
@ /opt/Xorg/lib/video-libs/libGL.so.1:[0xf668f14f] - 0x99c67c0
@ /opt/Xorg/lib/video-libs/libGL.so.1:[0xf668ee49] + (nil) 0x30000000
@ /lib/libc.so.6:[0xf677f8eb] + 0x99c21f0 0x158
@ /lib/libc.so.6:(_IO_file_doallocate+0x91)[0xf677ee61] + 0xbfb00480 0x400
@ /lib/libc.so.6:(_IO_setb+0x59)[0xf678d7f9] - 0xbfb00480