4

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

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

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

做什么?

Ps,进一步阅读总是值得赞赏的,并且在问题标记前面的帮助会很好。

4

1 回答 1

2

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

当然这不会成功:不居住or ; 它住在.malloclibgcclibstdc++libc

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

不用说,您绝不能在库中分配某些东西并在应用程序中释放它,反之亦然。

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

更新:

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

这一点没有错。由于您已将您的内容隐藏malloc在您的图书馆中,因此没有其他malloc可以gmtime_r使用的。

此外,gmtime_r不分配内存,GLIBC 本身内部使用除外,并且此类内存可以由 清理__libc_freeres因此在除使用 GLIBC 的.malloc

现在,fopen是您使用的另一个示例,fopen它进行了malloc记忆。显然,您想在您的库调用时fopen调用您的malloc(即使它不可见fopen),但malloc在应用程序调用时调用系统。但是怎么fopen知道是谁叫的呢?当然,您不是建议fopen遍历堆栈以确定它是由您的库还是由其他东西调用的?

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

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

于 2016-01-30T19:30:46.490 回答