标准C和C ++库中的malloc函数插入 [英] malloc function interposition in the standard C and C++ libraries
问题描述
我想编写一种共享库,以便可以将其内存使用情况与链接到的应用程序隔离开来.也就是说,如果将共享库称为libmemory.so
,然后调用malloc
,则我希望将该内存与用于服务于应用程序中对malloc
的调用的堆分开保存在单独的堆中.这个问题不是关于编写内存分配器的,而是关于将库和应用程序链接和加载在一起的.
I want to write a shared library in such a way that it is possible to isolate it’s memory usage from the application it is linked against. That is, if the shared library, let’s call it libmemory.so
, calls malloc
, I want to maintain that memory in a separate heap from the heap that is used to service calls to malloc
made in the application. This question isn't about writing memory allocators, it more about linking and loading the library and application together.
到目前为止,我一直在试验功能插入,符号可见性和链接技巧的组合.到目前为止,由于一件事,我无法做到这一点:标准库.我找不到一种方法来区分对内部使用malloc
的标准库的调用和在应用程序中发生的内部调用.这会导致问题,因为libmemory.so
中的任何标准库使用都会污染应用程序堆.
So far I’ve been experimenting with combinations of function interposition, symbol visibility, and linking tricks. So far, I can’t get this right because of one thing: the standard library. I cannot find a way to distinguish between calls to the standard library that internally use malloc
that happen in libmemory.so
versus the application. This causes an issue since then any standard library usage within libmemory.so
pollutes the application heap.
我当前的策略是在共享库中插入malloc
的定义作为隐藏符号.这很好用,并且所有库代码均按预期工作,当然,除了标准库外,该库在运行时会动态加载.自然地,我一直在尝试找到一种静态嵌入标准库用法的方法,以便在编译时将其插入libmemory.so
在libmemory.so
中.我尝试-static-libgcc
和-static-libstdc++
都没有成功(无论如何,似乎不建议这样做). 这是正确的答案吗?
My current strategy is to interpose definitions of malloc
in the shared library as a hidden symbol. This works nicely and all of the library code works as expected except, of course, the standard library which is loaded dynamically at runtime. Naturally, I’ve been trying to find a way to statically embed the standard library usage so that it would use the interposed malloc
in libmemory.so
at compile time. I’ve tried -static-libgcc
and -static-libstdc++
without success (and anyway, it seems this is discouraged). Is this the right answer?
做什么?
P.s.,总是希望您能进一步阅读,并且在问题标记方面的帮助也非常好.
P.s., further reading is always appreciated, and help on the question tagging front would be nice.
推荐答案
我尝试了-static-libgcc和-static-libstdc ++,但没有成功
I’ve tried -static-libgcc and -static-libstdc++ without success
课程 不会成功:malloc
不在libgcc
或libstdc++
中;它位于libc
.
Of course this wouldn't succeed: malloc
doesn't live in libgcc
or libstdc++
; it lives in libc
.
您要做的是静态链接libmemory.so
和其他malloc
替代实现,例如 jemalloc 和隐藏所有malloc
符号.然后,您的库和应用程序将具有绝对独立的堆.
What you want to do is statically link libmemory.so
with some alternative malloc
implementation, such as tcmalloc or jemalloc, and hide all malloc
symbols. Then your library and your application will have absolutely separate heaps.
毋庸置疑,您必须从不在您的库中分配某些内容并在应用程序中将其释放,反之亦然.
It goes without saying that you must never allocate something in your library and free it in the application, or vice versa.
从理论上讲,您也可以将系统libc.a
的malloc
部分链接到您的库中,但是实际上,GLIBC(和大多数其他UNIX C库)不支持部分静态链接(如果您链接libc.a
,您不得链接libc.so
).
In theory you could also link the malloc
part of system libc.a
into your library, but in practice GLIBC (and most other UNIX C libraries) does not support partially-static link (if you link libc.a
, you must not link libc.so
).
更新:
如果libmemory.so使用动态链接的标准库函数(例如gmtime_r),从而在运行时解析malloc,则libmemory.so错误地使用了运行时提供的malloc(显然是glibc提供的malloc
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
可以使用 no 其他malloc
.
There is nothing mistaken about that. Since you've hidden your malloc
inside your library, there is no other malloc
that gmtime_r
could use.
此外,gmtime_r
不会分配内存,除非GLIBC本身内部使用,并且__libc_freeres
可以清除此类内存,所以分配该内存将是错误.除了使用GLIBC的malloc
.
Also, gmtime_r
doesn't allocate memory, except for internal use by GLIBC itself, and such memory could be cleaned up by __libc_freeres
, so it would be wrong to allocate this memory anywhere other than using GLIBC's malloc
.
现在,fopen
是您使用的另一个示例,并且fopen
执行malloc
内存.显然,您希望fopen
在库调用时调用malloc
(即使fopen
不可见),但在应用程序调用时调用系统malloc
.但是fopen
如何知道谁叫它?您肯定不是在建议fopen
遍历堆栈以弄清楚它是由您的库还是由其他对象调用的?
Now, fopen
is another example you used, and fopen
does malloc
memory. Apparently you would like fopen
to call your malloc
(even though it's not visible to fopen
) when called by your library, but call system malloc
when called by the application. But how can fopen
know who called it? Surely you are not suggesting that fopen
walk the stack to figure out whether it was called by your library or by something else?
因此,如果您真的想对系统malloc
进行从不的调用,则必须静态链接 all 所使用的其他libc函数,并可能会调用malloc
(也将它们隐藏在您的媒体库中).
So, if you really want to make your library never call into system malloc
, then you would have to statically link all other libc functions that you use and that may call malloc
(and hide them in your library as well).
您可以使用uclibc
或dietlibc
之类的方法来实现.
You could use something like uclibc
or dietlibc
to achieve that.
这篇关于标准C和C ++库中的malloc函数插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!