我想以这样的方式编写一个共享库,以便可以将它的内存使用与它所链接的应用程序隔离开来.也就是说,如果共享库,我们称之为libmemory.so,调用malloc,我想将该内存保存在一个单独的堆中,该堆用于服务于应用程序中对malloc的调用.这个问题不是关于编写内存分配器,而是关于将库和应用程序链接和加载在一起.
到目前为止,我一直在尝试功能插入,符号可见性和链接技巧的组合.到目前为止,我无法做到这一点,因为有一件事:标准库.我找不到区分内部使用libmemory.so中发生的malloc与应用程序的标准库的调用的方法.这会导致问题,因为libmemory.so中的任何标准库使用都会污染应用程序堆.
我目前的策略是将共享库中malloc的定义作为隐藏符号.这很好用,并且所有库代码都按预期工作,当然除了在运行时动态加载的标准库.当然,我一直试图找到一种静态嵌入标准库用法的方法,以便在编译时使用libmemory.so中插入的malloc.我已经尝试了-static-libgcc和-static-libstdc没有成功(无论如何,似乎不鼓励这样做). this是正确答案吗?
做什么?
P.s.,进一步阅读总是受到赞赏,并且标记前面的问题的帮助会很好.
最佳答案
I’ve tried -static-libgcc and -static-libstdc++ without success
当然这不会成功:malloc不存在于libgcc或libstdc中;它住在libc.
你想要做的是将libmemory.so静态链接到一些替代的malloc实现,例如tcmalloc或jemalloc,并隐藏所有malloc符号.然后你的图书馆和你的应用程序将有完全独立的堆.
毫无疑问,您必须永远不要在库中分配内容并在应用程序中释放它,反之亦然.
从理论上讲,您还可以将系统libc.a的malloc部分链接到您的库中,但实际上GLIBC(以及大多数其他UNIX C库)不支持部分静态链接(如果链接libc.a,则不得链接libc .所以).
更新:
If libmemory.so makes use of a standard library function, e.g., gmtime_r, which is linked in dynamically, thereby resolving malloc at runtime, then libmemory.so mistakenly uses malloc provided at runtime (the one apparently from glibc
没有什么不对的.由于您已将malloc隐藏在库中,因此gmtime_r无法使用其他malloc.
此外,gmtime_r不分配内存,除了GLIBC本身的内部使用,并且这样的内存可以被__libc_freeres清除,因此除了使用GLIBC的malloc之外的任何地方分配这个内存是错误的.
现在,fopen是您使用的另一个示例,fopen执行malloc内存.显然你希望fopen在你的库调用时调用你的malloc(即使它对fopen不可见),但在应用程序调用时调用系统malloc.但是,怎么能知道谁叫它呢?当然你并没有建议fopen走出堆栈来弄清楚它是被你的图书馆还是其他东西调用的?
因此,如果您真的想让您的库永远不会调用系统malloc,那么您必须静态链接您使用的所有其他libc函数,并且可以调用malloc(并将它们隐藏在您的库中).
您可以使用uclibc或dietlibc之类的东西来实现这一目标.