Первый ответ не очень точен.
Короткий ответ для OP: Valgrind не обнаружит утечку в пользовательских пулах памяти, если вы не сообщите ему больше о своем распределителе.
Long ответ.
Когда вы запускаете valgrind
, запускаются два исполняемых файла. Во-первых, сам valgrind
. Это небольшое приложение, которое считывает несколько аргументов командной строки, устанавливает несколько переменных среды, затем просматривает гостевое приложение, чтобы определить его разрядность, а затем execve
соответствующий инструмент, например memcheck-x86-freebsd
.
Инструмент не связывает с ничем . Ни lib c, ни даже код запуска lib c. Точка входа находится в ассемблере, который создает новый стек и запускает valgrind_main
. Поскольку инструмент не связан ни с чем, он должен реализовать для себя все функции времени выполнения C, которые ему нужны или которые он хочет использовать. Сюда входят некоторые функции, которые компиляторы могут неявно генерировать. Например, код, который выполняет присваивание структуры, может привести к тому, что компилятор сгенерирует вызов memcpy()
. Это то, о чем идет речь в цитируемом тексте. Эти функции также предоставляются инструментом, а не lib c. Это не связано с механизмом перенаправления.
Итак, перенаправление. valgrind
будет иметь LD_PRELOAD
(или версию c для платформы, например LD_32_PRELOAD
). Это будет указывать на «основной» компонент (например, vgpreload_core-x86-freebsd.so
и компонент инструмента, например vgpreload_memcheck-x86-freebsd.so
. Инструмент выполняет работу загрузчика ссылок и помещает mmap
этих файлов в память. Во время этого процесса он будет прочтите информацию Elf
и обратите внимание на любые "специальные" функции. Эти функции используют сложную систему изменения имен, и инструмент распознает, что, например, _vgr10010ZU_libcZdsoZa_malloc
является заменой malloc
в libc
. Адреса из этих функций перенаправления сохраняются и будут использоваться при запуске гостя. Этот механизм также означает, что разные инструменты могут перенаправлять разные функции. Например, memcheck
необходимо перенаправить семейства функций malloc
и new
, а DRD
и Helgrind
необходимо перенаправить pthread_*
и sema_*
.
Для другого конца перенаправления инструмент также увидит целевые функции при загрузке библиотеки c. по умолчанию он не обрабатывает статически связанные приложения, но вы можете указать ему с помощью аргумента --soname-synonyms=somalloc=NONE
искать в гостевом исполняемом файле, где n он загружен.
Перенаправление не полностью заменяет целевую функцию, оно просто действует как прокладка, позволяющая инструменту отслеживать то, что запросила функция.
Теперь вернемся к sbrk
. Valgrind знает об этом, но только как системный вызов. Он проверит, что аргумент size
не получен из недопустимого хранилища. memcheck
не будет отслеживать память, как это происходит с malloc
. Если вы используете massif
с --pages-as-heap=yes
, тогда он будет профилировать использование sbrk
.
Если вы хотите, чтобы memcheck
проверял ваши пользовательские функции распределения, вам нужно сделать одно из двух.