2010-12-06 3 views
4

У меня есть mem_malloc() и mem_free(), определенные для меня, и я хочу использовать их для замены malloc() и free() и, следовательно, новых и Удалить.Как переопределить malloc() в Linux для использования в C++ new

Я определяю их следующим образом:

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); 
} 
} 

Однако, я получаю две ошибки ссылку:

[[email protected] 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) Как я могу получить многократно определенный таНос() и свободный() ошибки в уходите и просто возьмите мое определение, а не встроенное в него?

2) В какой библиотеке предоставляется dlopen() и друзей? Я ожидаю, что это будет встроено, но они не определены.

+0

новый и удалить не нужно звонить malloc. Существуют определенные семантики для их замены (реализация void * operator new (size_t size)) – 2010-12-06 14:47:06

ответ

4

Я предполагаю, что вы определяете таНос и свободный в файле main.cpp, что вы пытаетесь скомпилировать и что MEM_ALLOC и mem_free расположены в libmemnmf-0.a

Что, вероятно, происходит, является то, что некоторые ссылки в основной .cpp требуют объекты из glibc. В частности, что-то динамически загружает библиотеку (dlopen). Этот код включен в glibc (чтобы ответить на вопрос 2). Когда компоновщик включает объекты из glibc и обнаруживает, что для этих объектов требуется символ malloc/free, он попытается напрямую включить malloc/free из библиотеки glibc. Из-за вашего флага -статического компоновщика вся библиотека libmemnmf-0.a включена в ваш исполняемый файл статически. Это, очевидно, будет включать в ваш исполняемый файл другой malloc и бесплатный объект.

Что вам нужно сделать, это поместить malloc и бесплатные подпрограммы в отдельный файл .o и добавить этот файл где-нибудь в вашей link-команде, предпочтительно в конце (если вы не укажете стандартную библиотеку специальным образом эта линия). Файл .o будет удовлетворять всем запросам символов, и библиотека glibc найдет эти соответствия разрешенными всякий раз, когда требуются dlopen или другие объекты. Разница в том, что файл libmnef-0.a является библиотекой, а компоновщики по-разному работают с библиотеками, чем с простыми объектами (что связано с количеством проходов через библиотеку для разрешения символов, запрошенных объектами в этой библиотеке). В качестве альтернативы вы можете сбросить флаг -static, который, как я ожидаю, также устранит проблему, но у вас, вероятно, есть веская причина включить этот флаг для начала.

Если вы хотите переопределить поведение новых и удалить, вы также можете изучить перегрузку оператора new и оператор delete для классов, чтобы предоставить метод распределения класса или пул памяти.

2

Try:

#define free mem_free 
#define malloc mem_alloc 

После включая stdlib.h.

2.) dlopen() и друзей:

#include <dlfcn.h> 

компоновщика флаги: -ldl

См dlopen(3) man-page.

+0

-ldl решает dlopen() и друзей, но #define malloc/free не влияет на malloc/free calls из C++ new/delete. – WilliamKF 2010-12-07 01:45:26

1

Вы связываете по умолчанию с libc, который определяет malloc, попробуйте переименовать с #define. Длопены и т. Д. Определены в ld.

0

Вы можете передать приоритет библиотеке, используя переменную окружения LD_LIBRARY_PATH и LD_PRELOAD.

Это позволит вам предоставить пользовательские malloc и free в динамической библиотеке, которая будет преобладать над предоставленными libc. Я считаю, что это предпочтительнее, чем решение на основе #define.

0

Я искал этот ответ. Наконец я нашел кое-что, что работает для меня. У компоновщика есть опция --wrap = symbol, которую вы можете использовать.

Run

man ld 

и поиск "заворачивать", для деталей.

Я разместил это на случай, если кто-нибудь найдет этот вопрос, но ни один из ответов не будет работать для него, как это было с моим я.