Компиляция пользовательского malloc

Я написал пользовательскую библиотеку, реализующую malloc/calloc/realloc/free с использованием стандартных прототипов C, и понял, как скомпилировать ее в файл so. Я хочу протестировать библиотеку, связав с ней стандартное приложение? Что было бы хорошим способом сделать это? Когда у меня есть рабочая библиотека, я предполагаю, что могу просто загрузить ее с помощью LD_PRELOAD, но как мне заставить мои функции сосуществовать, но иметь приоритет над функциями системной библиотеки? Моим функциям нужно сделать вызов malloc, чтобы запустить память, поэтому я не могу просто полностью отказаться от stdlib... Помогите?


person conartist6    schedule 28.04.2011    source источник
comment
Я совершенно уверен, что мой ответ заключается в использовании динамического компоновщика.   -  person conartist6    schedule 28.04.2011


Ответы (3)


Функции, которые вы пытаетесь заменить, являются стандартными функциями C, а не макросами и не системными вызовами. Поэтому вам нужно просто дать своим функциям одинаковые имена и скомпилировать их в разделяемую библиотеку.

Затем используйте LD_PRELOAD для предварительной загрузки вашей библиотеки перед запуском двоичного файла. Так как все адреса резолвятся один раз, компоновщик вычислит адреса ваших функций и запомнит их имена и не будет потом искать их в стандартной библиотеке.

Этот подход может не сработать, если ваша программа связана со стандартной средой выполнения статически. Кроме того, это не будет работать в Mac OS X, так как есть другой API для интерполяции.

В Linux, например, для того, чтобы ваши функции сосуществовали (т.е. если вы хотите использовать систему malloc в собственной реализации malloc), вы должны открыть стандартную библиотеку вручную с помощью dlopen, найти там нужные вам функции с помощью dlsym и позвоните им позже по адресу.

person Community    schedule 28.04.2011
comment
Я думал, что столкнусь с большим количеством проблем, но после того, как я удалил стандартную библиотеку, загрузил malloc и вышел с dlsym, все скомпилировалось нормально. Спасибо! - person conartist6; 28.04.2011

Не записывайте свой malloc() в терминах malloc() — пишите его, используя sbrk, который получает память непосредственно из ОС.

person Ernest Friedman-Hill    schedule 28.04.2011
comment
интересное предложение. Я посмотрю на это. - person conartist6; 28.04.2011
comment
В некоторых системах sbrk() больше не доступен. Например, в моем текущем Mac OS X человек говорит The brk and sbrk functions are historical curiosities left over from earlier days before the advent of virtual memory management., и если вы посмотрите полный исходный код функции, это будет еще смешнее: errno = ENOMEM; return((void *)-1); - person achedeuzot; 20.01.2015

Если у вас есть контроль над исходным кодом, который должен использовать эту библиотеку, вот одна из возможностей. Используйте разные имена функций: вместо malloc, например, назовите ее newCoolMalloc. Этот метод иногда проще и не зависит от специальных опций компоновщика.

Затем в своем коде используйте #define, чтобы код вызывал нужный набор функций. Вы можете #define malloc сделать что-то другое. Например:

#define malloc newCoolMalloc
#define free   newCoolFree

Однако, если вы делаете это, вы должны быть очень осторожны, чтобы включать это постоянно. В противном случае вы рискуете использовать stdlib malloc в одном месте, а затем свой собственный free в другом, что приведет к грязным ошибкам. Один из способов смягчить эту ситуацию — использовать (если возможно) в собственном коде собственные имена для функций распределения и свободных функций. Тогда легче убедиться, что вызывается правильный. Вы можете определить различные пользовательские имена для ваших собственных функций malloc или даже для исходных функций malloc stdlib.

Например, вы можете использовать mallocPlaceHolder в качестве фактического имени в коде:

someThing = mallocPlaceHolder( nbytes );

Тогда ваши определения будут выглядеть примерно так:

#define mallocPlaceHolder myCoolMalloc

Если на самом деле не существует функции вида mallocPlaceHolder (и связанной с ней бесплатной), это позволяет избежать смешивания разных библиотек.

person Mark Wilkins    schedule 28.04.2011
comment
К сожалению, это не работает для меня. Я хочу протестировать свой распределитель, запустив чужое приложение с использованием этой библиотеки. Теоретически я мог бы перекомпилировать с этими включениями, но время и усилия будут сэкономлены с помощью LD_PRELOAD. - person conartist6; 28.04.2011