tcmalloc: как мне переопределить вызовы malloc при статической компиляции? - PullRequest
8 голосов
/ 12 октября 2009

Когда я использую LD_PRELOAD=/usr/local/lib/libtcmalloc.so, все мои вызовы malloc становятся вызовами tcmalloc. Однако, когда я статически связываюсь с libtcmalloc, я обнаруживаю, что вызывается прямой malloc, если я все еще не использую настройку LD_PRELOAD.

Так как я могу статически скомпилировать tcmalloc таким образом, чтобы мои mallocs подключались к tcmalloc?

Примечания:

  • Я использую много нового C ++ и т. Д., Поэтому просто # определение malloc для tcmalloc не будет работать
  • Возможно, я должен использовать malloc_hook сам, но я бы думал, что смогу заставить tcmalloc сделать это для меня, так как он явно делает это при динамическом соединении

Ответы [ 2 ]

12 голосов
/ 12 октября 2009

Символы разрешаются на основе первого совпадения. Вы должны убедиться, что компоновщик ищет файл libtcmalloc.a перед libc.a. Я предполагаю, что вы явно не ссылаетесь на libc.a, так как обычно вам это не нужно. Решение состоит в том, чтобы указать -nostdlibs, а затем явно связать все необходимые библиотеки в том порядке, в котором вы хотите их искать. Обычно что-то вроде:

-nostdlibs -llibtcmalloc -llibm -llibc -llibgcc

Другое решение, которое может быть проще, - это связать объектные файлы, необходимые для разрешения tcmalloc, а не статическую библиотеку, поскольку объектные файлы имеют приоритет над библиотеками в разрешении символов.

1 голос
/ 25 апреля 2018

TCMalloc переопределяет все вызовы функций выделения / освобождения, включая все варианты New / Delete и C API ( malloc / free / calloc / перераспределить / valloc / pvalloc / mem_aligned / malloc_usable_size ) Для платформ, основанных на gcc, он выполняет переопределение с помощью директивы alias.

Я использую много новых C ++ и т. Д., Поэтому просто # определение malloc для tcmalloc не сработает

В заголовках TCMalloc malloc уже имеет псевдоним tc_malloc , поэтому это не имеет никакого эффекта. Например:

#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn), used))
void* malloc(size_t size) __THROW               ALIAS(tc_malloc)

Что касается New , обратите внимание, что в отличие от glibc и других реализаций New (windows), которые просто обертывают malloc, команда tcmalloc New не вызывает malloc.

TCMalloc Новый имеет псевдоним tc_new и tc_newarray , который вызовет "магический" диспетчер памяти TCMalloc, а в некоторых случаях, как libc malloc, будет инициировать системный вызов sbrk / brk.

Еще одна вещь, которую вам нужно сделать, это убедиться, что gcc не связывается с вариантами malloc libc. Для этого, пожалуйста, добавьте флаги C ++ в Makefile следующим образом:

-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free

Также не забудьте указать статическую библиотеку TCMalloc:

LIB_TCMALLOC = $(TCMALLOC_LIB_DIR)/libtcmalloc_minimal.a
LIB_DIR := .... -L$(TCMALLOC_LIB_DIR) ...
LIBS := ... -static $(LIB_TCMALLOC) ...

Возможно, мне придется использовать malloc_hook самостоятельно, но я бы подумал, что смогу заставить tcmalloc сделать это для меня, поскольку он явно делает это при динамическом соединении

TCMalloc не использует malloc_hooks, который в настоящее время считается устаревшим из-за проблем безопасности потоков. Он просто использует тот факт, что методы выделения памяти являются слабыми символами. Он переопределяет эти символы, используя псевдонимы (в gcc) __attribute__((alias)) из-за вызовов функций.

Пожалуйста, обратитесь к: https://github.com/gperftools/gperftools/blob/master/README

...