关于重写 C 标准库函数以及如何将所有内容链接在一起的问题

发布于 2024-10-20 11:51:48 字数 498 浏览 5 评论 0原文

我自己实现了 _init 、 malloc 、 free (和其他)。

在这些函数中,我使用 dlfcn.h (dlopen 、 dlsym 等)库来调用实际的标准版本。我将其放入一个文件中并将它们编译为共享库( memory.so )。当我希望运行可执行文件并使其调用我的这些函数版本时,我只需设置 LD_PRELOAD=memory.so 。

问题是我有 memory.c 依赖的许多其他模块。其中包括一个包含扫描 elf 文件函数的文件 (symbols.c) 和我自己的哈希表实现 (hashtable.c),我用它来跟踪内存泄漏等。

我的问题是是否有办法单独编译 hashtable.c & symbols.c 中的所有 malloc 引用均由标准库解析,而不是由 memory.c 中包含的引用解析。我当然可以在 memory.c 依赖的所有内容上使用 dlfcn.h 库,但如果有办法避免这种情况,我会更喜欢它。

我还没有完全弄清楚链接是如何工作的,所以任何帮助将不胜感激。

谢谢

I made my own implementation of _init , malloc , free ( and others ).

Inside these functions I use the dlfcn.h (dlopen , dlsym etc) library to call the actual standard versions. I put then in a single file and compile them as a shared library ( memory.so ). When I wish to run an executable and make it call my versions of these functions I simply set LD_PRELOAD=memory.so .

The problem is that I have a number of other modules which memory.c depends on. These include a file containing functions to scan elf files ( symbols.c ) and my own implementation of a hash table ( hashtable.c ) which I use to keep track of memory leaks among others.

My question is if there is a way to separately compile hashtable.c & symbols.c so any malloc references are resolved with the standard library and not with the ones included on memory.c. I could of course use the dlfcn.h libraries on everything that memory.c depends on but I would prefer it if there was a way to avoid that.

I still haven't completely figured out how linking works so any help would be appreciated.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

合久必婚 2024-10-27 11:51:49

首先,需要注意的是,无需为 Linux 中的内存调试器执行您想要执行的操作,因为 glibc 为内存函数提供了特定的挂钩函数(请参阅:http://www.gnu.org/s/libc/manual/html_node/Allocation-Debugging.html

但是忽略这一点,一般的解决方案是不使用 dlopen() 来获取 dlsym() 的 glibc 引用,而是使用神奇的句柄 RTLD_NEXT。以下是 dlopen() 手册页中的相关部分:

“有两个特殊的伪句柄,RTLD_DEFAULT 和 RTLD_NEXT。前者将使用默认库搜索顺序查找所需符号的第一次出现。后者将查找下一个出现的符号。”在当前库之后的搜索顺序中出现函数,这允许为另一个共享库中的函数提供包装器。”

例如,请参见: http://developers.sun.com/solaris/articles/lib_interposers_code.html

First it is important to note there is no need to do what you want to do for memory debuggers in Linux as glibc provides specific hook functions for memory functions (see: http://www.gnu.org/s/libc/manual/html_node/Allocation-Debugging.html)

But disregarding this, the general solution is to NOT use dlopen() to get a reference to glibc for dlsym() but rather use the magical handle RTLD_NEXT. Here is the relevant part from the dlopen() man page:

"There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library."

See for example: http://developers.sun.com/solaris/articles/lib_interposers_code.html

岁月蹉跎了容颜 2024-10-27 11:51:49

您可以看一下电围栏。它重写了许多标准函数来进行各种内存调试。

You could take a look at electric fence. It overrides a lot of standard functions to do various memory debugging.

青芜 2024-10-27 11:51:48

如果您使用 glibc,则可以使用替代的非重写函数名称:

[max@truth ~]$ nm --defined-only --dynamic /lib64/libc.so.6 | egrep "malloc\b"
0000003e56079540 T __libc_malloc
0000003e56079540 T malloc

请注意上面的相同函数地址。换句话说,malloc() 函数被赋予了两个名称,因此原始 malloc() 版本可以在 __libc_malloc() 名称下使用case malloc() 已被插入。

对 glibc 源代码的快速 grep 显示 __libc_malloc() 的唯一调用者是 mcheck。这些函数别名是 glibc 实现细节,并且没有它们的标头。 malloc/mcheck.c 声明内部函数如下:

extern __typeof (malloc) __libc_malloc;
extern __typeof (free) __libc_free;
extern __typeof (realloc) __libc_realloc;

其他 C 库可能有不同命名的别名,因此使用 dlsym() 获取原始 malloc() 地址更为方便便携的。

If you are working with glibc you can use alternative non-overriden function names:

[max@truth ~]$ nm --defined-only --dynamic /lib64/libc.so.6 | egrep "malloc\b"
0000003e56079540 T __libc_malloc
0000003e56079540 T malloc

Note the same function address in the above. In other words, malloc() function is given two names, so that the original malloc() version is available under __libc_malloc() name in case malloc() has been interposed.

A quick grep on glibc sources reveals the only caller of __libc_malloc() is mcheck. These function aliases are a glibc implementation detail and there is no header for them. malloc/mcheck.c declares the internal functions as below:

extern __typeof (malloc) __libc_malloc;
extern __typeof (free) __libc_free;
extern __typeof (realloc) __libc_realloc;

Other C libraries may have differently named aliases, so using dlsym() to get the original malloc() address is more portable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文