问题
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.
回答1:
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.
回答2:
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.
回答3:
You are linking by default to libc which defines malloc, try renaming with a #define. The dlopen etc. are defined in ld.
回答4:
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.
回答5:
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.
来源:https://stackoverflow.com/questions/4364647/how-to-redefine-malloc-in-linux-for-use-in-c-new