Может ли кто-нибудь дать быстрое объяснение на высшем уровне того, как работает Valgrind? Пример: как узнать, когда память выделена и освобождена?
Valgrind в основном запускает ваше приложение в «песочнице». Во время работы в этой песочнице он может вставлять собственные инструкции для выполнения расширенной отладки и профилирования.
Из руководства:
Затем ваша программа запускается на синтетическом процессоре, предоставляемом ядром Valgrind. Когда новый код выполняется впервые, ядро передает код выбранному инструменту. Инструмент добавляет к этому свой собственный инструментальный код и возвращает результат в ядро, которое координирует дальнейшее выполнение этого инструментированного кода.
По сути, valgrind предоставляет виртуальный процессор, который выполняет ваше приложение. Однако перед обработкой инструкций вашего приложения они передаются в инструменты (например, memcheck). Эти инструменты похожи на плагины, и они могут изменять ваше приложение до того, как оно будет запущено на процессоре.
Самое замечательное в этом подходе заключается в том, что вам вообще не нужно изменять или повторно связывать свою программу, чтобы запустить ее в valgrind. Это действительно заставляет вашу программу работать медленнее, однако valgrind не предназначен для измерения производительности или запуска во время обычного выполнения вашего приложения, поэтому на самом деле это не проблема.
Valgrind - это инструмент динамического двоичного анализа (DPA), который использует инфраструктуру динамического двоичного анализа (DPI) для проверки распределения памяти, обнаружения взаимоблокировок и профилирования приложений. Инфраструктура DPI имеет собственный диспетчер низкоуровневой памяти, планировщик, обработчик потоков и обработчик сигналов. Набор инструментов Valgrind включает такие инструменты, как
Инструмент Valgrind использует механизм дизассемблирования и повторного синтеза, при котором он загружает приложение в процесс, дизассемблирует код приложения, добавляет код инструментария для анализа, собирает его обратно и запускает приложение. Он использует Just Intime Compiler (JIT) для встраивания приложения с кодом инструментария.
Valgrind Core дизассемблирует код приложения и передает фрагмент кода плагину инструмента для инструментирования. Плагин инструмента добавляет код анализа и собирает его обратно. Таким образом, Valgrind предоставляет гибкость для написания собственного инструмента поверх фреймворка Valgrind. Valgrind использует теневые регистры и теневую память для обработки инструкций чтения / записи, системного вызова чтения / записи, распределения стека и кучи.
Valgrind предоставляет оболочки для системного вызова и регистры для обратных вызовов до и после каждого системного вызова, чтобы отслеживать доступ к памяти как часть системного вызова. Таким образом, Valgrind - это уровень абстракции ОС между операционной системой Linux и клиентским приложением.
На диаграмме показаны 8 этапов Valgrind:
источник
valgrind находится в качестве слоя между вашей программой и ОС, перехватывая вызовы ОС, запрашивая (де) выделение памяти, и записывая то, что обрабатывается до того, как фактически выделяет память и передает обратно эквивалент. По сути, так работает большинство профилировщиков кода, за исключением гораздо более низкого уровня (системные вызовы вместо вызовов программных функций).
источник
Здесь вы можете найти полезную информацию:
Кроме того, ознакомьтесь с LD_PRELOAD.
источник
Valgrind - это, по сути, виртуальная машина, которая выполняет вашу программу. Это виртуальная архитектура, которая перехватывает каждый вызов для выделения / освобождения памяти.
источник