Вставка функции malloc в стандартные библиотеки C и C++
Я хочу написать разделяемую библиотеку таким образом, чтобы можно было изолировать использование памяти от приложения, с которым она связана. То есть, если общая библиотека, давайте назовем это libmemory.so
, звонки malloc
Я хочу сохранить эту память в отдельную кучу из кучи, которая используется для обслуживания вызовов malloc
сделано в приложении. Этот вопрос не о написании распределителей памяти, а о связывании и загрузке библиотеки и приложения вместе.
До сих пор я экспериментировал с комбинациями функций, видимости символов и трюков связывания. Пока что я не могу понять это по одной причине: стандартная библиотека. Я не могу найти способ различать вызовы стандартной библиотеки, которые используют внутри malloc
это происходит в libmemory.so
по сравнению с приложением. Это вызывает проблему с тех пор любое использование стандартной библиотеки в libmemory.so
загрязняет приложение кучи.
Моя текущая стратегия состоит в том, чтобы вставить определения malloc
в общей библиотеке как скрытый символ. Это работает хорошо, и весь код библиотеки работает, как и ожидалось, за исключением, конечно, стандартной библиотеки, которая загружается динамически во время выполнения. Естественно, я пытался найти способ статически встраивать использование стандартной библиотеки, чтобы она использовала вставленную malloc
в libmemory.so
во время компиляции. я пробовал -static-libgcc
а также -static-libstdc++
без успеха (и в любом случае, кажется, это не рекомендуется). Это правильный ответ?
Что?
Ps, дальнейшее чтение всегда ценится, и помощь в вопросе пометки фронта была бы хорошей.
1 ответ
Я пробовал -static-libgcc и -static-libstdC++ без успеха
Конечно, это не удастся: malloc
не живет в libgcc
или же libstdc++
; оно живет в libc
,
То, что вы хотите сделать, это статически ссылка libmemory.so
с какой-то альтернативой malloc
реализации, такие как tcmalloc или jemalloc, и скрыть все malloc
символы. Тогда ваша библиотека и ваше приложение будут иметь совершенно разные кучи.
Само собой разумеется, что вы никогда не должны выделять что-либо в своей библиотеке и освобождать это в приложении, или наоборот.
В теории вы могли бы также связать malloc
часть системы libc.a
в вашу библиотеку, но на практике GLIBC (и большинство других библиотек UNIX C) не поддерживает частично статическое соединение (если вы связываете libc.a
Вы не должны связывать libc.so
).
Обновить:
Если libmemory.so использует стандартную библиотечную функцию, например, gmtime_r, которая динамически связана, разрешая таким образом malloc во время выполнения, то libmemory.so по ошибке использует malloc, предоставленную во время выполнения (очевидно, из glibc
В этом нет ничего ошибочного. Так как вы спрятали malloc
внутри вашей библиотеки нет другого malloc
тот gmtime_r
мог бы использовать.
Также, gmtime_r
не выделяет память, за исключением внутреннего использования самой GLIBC, и такая память может быть очищена __libc_freeres
, поэтому было бы неправильно выделять эту память где-либо, кроме использования GLIBC malloc
,
Сейчас, fopen
другой пример, который вы использовали, и fopen
делает malloc
объем памяти. Видимо, вы хотели бы fopen
позвонить вашему malloc
(хотя это не видно fopen
) когда вызывается из вашей библиотеки, но вызывает систему malloc
когда вызывается приложением. Но как можно fopen
знаете кто это назвал? Конечно, вы не предлагаете fopen
пройтись по стеку, чтобы выяснить, вызван ли он вашей библиотекой или чем-то еще?
Итак, если вы действительно хотите, чтобы ваша библиотека никогда не заходила в систему malloc
тогда вам придется статически связать все другие функции libc, которые вы используете и которые могут вызывать malloc
(и спрятать их в своей библиотеке).
Вы могли бы использовать что-то вроде uclibc
или же dietlibc
чтобы достичь этого.