Вставка функции 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 чтобы достичь этого.

Другие вопросы по тегам