如何在 Linux 中重新定义 malloc() 以在 C++ 中使用新的

发布于 2024-10-06 05:09:55 字数 1270 浏览 0 评论 0原文

我为我定义了 mem_malloc() 和 mem_free(),我想用它们来替换 malloc() 和 free() 以及 C++ 的 new 和 delete。

我将它们定义如下:

extern "C" {

extern void *mem_malloc(size_t);
extern void mem_free(void *);

void *
malloc(size_t size) {
  return mem_malloc(size);
}

void
free(void *memory) {
  mem_free(memory);
}
}

但是,我收到两个链接错误:

[user@machine test]$ g++ -m32 -pthread main.cpp -static  libmemnmf-O.a
/usr/lib/../lib/libc.a(malloc.o): In function `free':
(.text+0x153c): multiple definition of `free'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x842): first defined here
/usr/lib/../lib/libc.a(malloc.o): In function `malloc':
(.text+0x3084): multiple definition of `malloc'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x856): first defined here
libmemnmf-O.a(mem_debug.o): In function `mem_init_debug_routines':
mem_debug.c:(.text+0x83c): undefined reference to `dlopen'
mem_debug.c:(.text+0x89d): undefined reference to `dlsym'
mem_debug.c:(.text+0xa03): undefined reference to `dlclose'
mem_debug.c:(.text+0xa24): undefined reference to `dlclose'
mem_debug.c:(.text+0xa2e): undefined reference to `dlerror'
collect2: ld returned 1 exit status

1)如何消除多重定义的 malloc() 和 free() 错误,只采用我的定义而不是内置的定义?

2)什么库提供了 dlopen() 和朋友?我希望这是内置的,但它们是未定义的。

I have a mem_malloc() and mem_free() defined for me and I want to use them to replace the malloc() and free() and consequently C++'s new and delete.

I define them as follows:

extern "C" {

extern void *mem_malloc(size_t);
extern void mem_free(void *);

void *
malloc(size_t size) {
  return mem_malloc(size);
}

void
free(void *memory) {
  mem_free(memory);
}
}

However, I get two link errors:

[user@machine test]$ g++ -m32 -pthread main.cpp -static  libmemnmf-O.a
/usr/lib/../lib/libc.a(malloc.o): In function `free':
(.text+0x153c): multiple definition of `free'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x842): first defined here
/usr/lib/../lib/libc.a(malloc.o): In function `malloc':
(.text+0x3084): multiple definition of `malloc'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x856): first defined here
libmemnmf-O.a(mem_debug.o): In function `mem_init_debug_routines':
mem_debug.c:(.text+0x83c): undefined reference to `dlopen'
mem_debug.c:(.text+0x89d): undefined reference to `dlsym'
mem_debug.c:(.text+0xa03): undefined reference to `dlclose'
mem_debug.c:(.text+0xa24): undefined reference to `dlclose'
mem_debug.c:(.text+0xa2e): undefined reference to `dlerror'
collect2: ld returned 1 exit status

1) How do I get the multiply defined malloc() and free() errors to go away and just take my definition and not the built in one?

2) What library provides dlopen() and friends? I'd expect this to be built in, but they are undefined.

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

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

发布评论

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

评论(5

分開簡單 2024-10-13 05:09:55

我假设您在尝试编译的 main.cpp 文件中定义了 malloc 和 free,并且 mem_alloc 和 mem_free 位于 libmemnmf-0.a 中

,可能发生的情况是 main.cpp 中的某些引用需要来自 glibc 的对象。具体来说,就是动态加载库(dlopen)。该代码包含在 glibc 中(回答问题 2)。
当链接器包含来自 glibc 的对象并发现这些对象需要 malloc/free 符号时,它将尝试直接包含来自 glibc 库的 malloc/free 符号。
由于您的 -static 链接器标志,整个 libmemnmf-0.a 库静态地包含在您的可执行文件中。这显然会在可执行文件中包含另一个 malloc 和 free 对象。

您应该做的是将 malloc 和 free 例程放在单独的 .o 文件中,并将该文件添加到链接命令中的某个位置,最好是在末尾(假设您没有在该行上以特殊方式指定标准库)。 .o 文件将满足所有符号请求,并且 glibc 库将在 dlopen 或其他对象需要它们时找到已解析的这些匹配。
区别在于 libmnef-0.a 文件是一个库,链接器处理库的方式与处理简单对象的方式不同(这与通过库来解析该库中对象请求的符号的次数有关)。
或者,您可以删除 -static 标志,我希望这也能解决问题,但您可能有充分的理由首先包含该标志。

如果您想重写 new 和 delete 的行为,您还可以考虑为类重载operator new 和operator delete,以提供特定于类的分配方法或内存池。

I assume you define malloc and free in the main.cpp file that you try to compile and that mem_alloc and mem_free are located in libmemnmf-0.a

What is probably happening, is that some references in main.cpp require objects from glibc. Specifically, something is dynamically loading a library (dlopen). This code is included in glibc (to answer question 2).
When the linker includes the objects from glibc and finds that these objects require a malloc/free symbol, it will try to include the malloc/free from the glibc library directly.
Due to your -static linker flag, the entire libmemnmf-0.a library is included statically in your executable. This will obviously include another malloc and free object in your executable.

What you should do is put the malloc and free routines in a separate .o file and add that file somewhere in your link-command, preferrably on the end (assuming you do not specify the standard library in a special way on that line). The .o file will satisfy all symbol requests and the glibc library will find these matches resolved whenever dlopen or other objects require them.
The difference is that the libmnef-0.a file is a library and linkers deal differently with libraries than with simple objects (which has to do with the number of passes through a library to resolve symbols requested by objects in that library).
Alternatively, you can drop the -static flag, which I expect to resolve the issue as well, but you probably have a good reason to include that flag to start with.

If you want to override the behaviour of new and delete, you can also look into overloading operator new and operator delete for classes to provide a class-specific allocation method or memory pool.

ゝ偶尔ゞ 2024-10-13 05:09:55

尝试:

#define free mem_free
#define malloc mem_alloc

之后包含stdlib.h

2.) dlopen() 和朋友:

#include <dlfcn.h>

链接器标志:-ldl

请参阅 dlopen(3) 手册页

Try:

#define free mem_free
#define malloc mem_alloc

After including stdlib.h.

2.) dlopen() and friends:

#include <dlfcn.h>

Linker flags: -ldl

See the dlopen(3) man-page.

神魇的王 2024-10-13 05:09:55

默认情况下,您链接到定义 malloc 的 libc,请尝试使用 #define 重命名。 dlopen 等在 ld 中定义。

You are linking by default to libc which defines malloc, try renaming with a #define. The dlopen etc. are defined in ld.

暖树树初阳… 2024-10-13 05:09:55

您可以使用 LD_LIBRARY_PATHLD_PRELOAD 环境变量为库指定优先级。

这将允许您在动态库中提供自定义的mallocfree,这将主导libc提供的库。我相信这比基于 #define 的解决方案更好。

You can give precedence to a library using the LD_LIBRARY_PATH and LD_PRELOAD environment variable.

This will allow to you to provide a custom malloc and free in a dynamic library which will predominate the libc provided ones. I believe this is preferable over a #define-based solution.

等待圉鍢 2024-10-13 05:09:55

我一直在寻找这个答案。最后我找到了适合我的东西。链接器有 --wrap=symbol 选项可供您使用。

运行

man ld

并搜索“wrap”以获取详细信息。

我发布此内容是为了防止有人发现这个问题,但没有一个答案对他有用,就像我自己的情况一样。

I was looking for this answer to. Finally I found something that works for me. Linker has --wrap=symbol option that you can use.

Run

man ld

and search for "wrap", for details.

I posted this in case that somebody finds this question but none of answers work for him, just as it was case with my self.

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