标准C和C ++库中的malloc函数插入 [英] malloc function interposition in the standard C and C++ libraries

查看:147
本文介绍了标准C和C ++库中的malloc函数插入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一种共享库,以便可以将其内存使用情况与链接到的应用程序隔离开来.也就是说,如果将共享库称为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.solibmemory.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不在libgcclibstdc++中;它位于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.amalloc部分链接到您的库中,但是实际上,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).

您可以使用uclibcdietlibc之类的方法来实现.

You could use something like uclibc or dietlibc to achieve that.

这篇关于标准C和C ++库中的malloc函数插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆