标准 C 和 C++ 库中的 malloc 函数干预



我想编写一个共享库,以便可以将其内存使用情况与链接的应用程序隔离开来。也就是说,如果共享库,我们称之为libmemory.so,调用malloc,我想将该内存维护在与用于为应用程序中malloc调用提供服务的堆不同的堆中。这个问题不是关于编写内存分配器,而是关于链接和加载库和应用程序。

到目前为止,我一直在尝试函数插入、符号可见性和链接技巧的组合。到目前为止,我无法做到这一点,因为一件事:标准库。我找不到一种方法来区分对内部使用的标准库的调用malloc发生在libmemory.so与应用程序中。这会导致一个问题,因为libmemory.so内的任何标准库使用都会污染应用程序堆。

我目前的策略是将共享库中malloc的定义作为隐藏符号插入。这工作得很好,所有库代码都按预期工作,当然,除了在运行时动态加载的标准库。当然,我一直在尝试找到一种方法来静态嵌入标准库用法,以便它在编译时使用libmemory.so中的插入malloc。我尝试过-static-libgcc-static-libstdc++但没有成功(无论如何,这似乎不鼓励)。这是正确的答案吗?

怎么办?

附言,进一步阅读总是不胜感激的,在问题标记方面提供帮助会很好。

我尝试过-static-libgcc和-static-libstdc++但没有成功

当然,这不会成功:malloc不住在libgcclibstdc++,而是住在libc

您要做的是libmemory.so与一些替代malloc实现(例如 tcmalloc 或 jemalloc)静态链接,并隐藏所有malloc符号。然后,您的库和应用程序将具有绝对独立的堆。

不言而喻,您永远不能在库中分配某些内容并在应用程序中释放它,反之亦然。

理论上你也可以将系统libc.amalloc部分链接到你的库中,但实际上GLIBC(以及大多数其他UNIX C库)不支持部分静态链接(如果你链接libc.a,你一定不能链接libc.so)。

更新:

如果 libmemory.so 使用动态链接的标准库函数,例如gmtime_r,从而在运行时解析malloc,那么 libmemory.so 错误地使用了运行时提供的malloc(显然来自glibc

没有错。由于您已将malloc隐藏在库中,因此gmtime_r无法使用其他malloc

此外,除了 GLIBC 本身的内部使用外,gmtime_r 不会分配内存,并且此类内存可以通过 __libc_freeres 清理,因此在使用 GLIBC 的malloc之外的任何地方分配此内存都是错误的

现在,fopen是您使用的另一个示例,fopen确实malloc内存。显然,您希望fopen在库调用时调用malloc(即使fopen不可见),但在应用程序调用时调用系统malloc。但是fopen怎么知道是谁叫的呢?当然,您不是建议fopen走过堆栈来确定它是由您的库调用还是由其他东西调用?

因此,如果您真的想让您的库永远不会调用系统 malloc ,那么您必须静态链接您使用的所有其他 libc 函数,这些函数可能会调用malloc(并将它们隐藏在您的库中)。

您可以使用类似uclibcdietlibc之类的东西来实现这一点。

相关内容

  • 没有找到相关文章

最新更新