【发布时间】:2016-05-06 11:29:18
【问题描述】:
我想编写一个共享库,以便可以将它的内存使用与它所链接的应用程序隔离开来。也就是说,如果共享库,我们称之为libmemory.so,调用malloc,我想将该内存保留在一个单独的堆中,该堆用于为应用程序中对malloc的调用提供服务。这个问题不是关于编写内存分配器,而是关于将库和应用程序链接和加载在一起。
到目前为止,我一直在试验函数插入、符号可见性和链接技巧的组合。到目前为止,由于一件事,我无法做到这一点:标准库。我无法找到一种方法来区分对内部使用malloc 的标准库的调用(发生在libmemory.so 和应用程序中)。这会导致一个问题,因为在libmemory.so 中使用任何标准库都会污染应用程序堆。
我目前的策略是在共享库中插入malloc 的定义作为隐藏符号。这工作得很好,所有库代码都按预期工作,当然,在运行时动态加载的标准库除外。自然地,我一直在尝试找到一种静态嵌入标准库用法的方法,以便它在编译时使用libmemory.so 中插入的malloc。我试过-static-libgcc 和-static-libstdc++ 都没有成功(无论如何,这似乎是不鼓励的)。 this 是正确答案吗?
做什么?
P.s.,进一步阅读总是值得赞赏的,在问题标记方面的帮助会很好。
【问题讨论】:
-
与 Windows 不同,Unix 用户空间非常倾向于使用相同分配器的进程中的所有内容。仅仅在同一进程中拥有两个
malloc的实现很容易导致灾难性的故障,因为没有人担心将 A_malloc 与 A_free 以及 B_malloc 与 B_free 匹配,这些实现可能会为它们中的哪一个发生争执允许使用非零参数调用sbrk,等等等等。 -
因此,为了提供任何有用的答案,我们需要更多地了解您为什么认为您首先需要做这件事。你试图解决的更大的问题是什么?为什么这似乎是阻力最小的路径?大致了解
libmemory.so做了什么以及它使用了哪些 C 和 C++ 库函数也很有用。 -
感谢@zwol 的回复。我正在构建一个分布式共享内存分配器作为共享对象,并希望找到一种方法来分离共享对象与应用程序使用的内存。共享对象很复杂:它有一个分配器,有一个嵌入式 HTTP 服务器等。它充分利用了内存本身(尽管我在编写的所有库代码中都使用了一个特殊分配器的内存)。作为状态,问题是标准库使用的内存......例如,下降到
fopen或gmtime_r可能会在内部调用malloc,从而使用要使用的应用程序的堆分配器。 -
首先想到的是:也许共享库的大部分功能应该被提取到一个单独的守护进程中。
-
这是一个重大的设计更改,但肯定是可能的。在我改变路线之前,我可以用我当前的设置调查任何其他方法吗?
标签: c unix malloc shared-libraries function-interposition