Pin 2.12 User Guide / Pin 2.12 User Guide: How to Instrument with Pin

← →
Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

Оглавление
Pin
Pin инструменты
Замечания
Гранулярность инструментирования
Символы
Поддержка чисел с плавающей точкой
Обработка многопоточных приложений
Как избежать deadlock'ов в многопоточных приложениях

noam 12.05.13 в 17:26

0

Pin

noam 12.05.13 в 17:22

0

Наилучшим образом можно описать Pin как "just in time" (JIT) компилятор. Однако на вход этого компилятора подается не байт код, а обычный исполняемый файл. Pin перехватывает запуск первой машинной команды и генерирует ("компилирует") новый код, начинающийся на этой команде. Затем он передает управление на сгенерированный код. Сгенерированный код почти идентичен первоначальному, кроме того, что Pin гарантирует, что он вернет себе управление после того, как код выполнится. После чего Pin генерирует еще код и продолжает выполнение. Pin делает это эффективно, сохраняя весь сгенерированный код в памяти, так, чтобы его можно было повторно использовать и переключатся с одного кода на другой.

noam 05.05.13 в 14:41

0

В JIT режиме единственным кодом, который будет запущен, является сгенерированный код. Первоначальный код используется только для ссылки. Во время генерации кода, Pin позволяет добавлять свой собственный код.

noam 05.05.13 в 14:45

0

Pin обеспечивает то, что все команды будут запущены. Не важно в какой части программы они располагаются. Хотя есть несколько исключений, вообще говоря, если команда никогда не запускалась, Pin обойдет ее стороной.

noam 05.05.13 в 14:54

0

Pin инструменты

noam 12.05.13 в 17:21

0

Инструментарий содержит две части:

noam 05.05.13 в 14:55

0

Инструментирование состоит из двух частей:

noam 13.05.13 в 15:29

0

- Механизм, который решает какой код будет вставлен и куда.

noam 05.05.13 в 14:56

0

- Механизма, который решает какой код будет вставлен и куда.

noam 13.05.13 в 15:29

0

- Код для выполнения в местах вставки.

noam 05.05.13 в 14:57

0

- Механизма, который решает какой код будет вставлен и куда.

noam 13.05.13 в 15:30

0

Обе компоненты находятся в одном исполняемом файле - Pin инструменте. Pin инструменты можно понимать как плагины, который позволяют модифицировать процесс генерации кода внутри Pin'a.

noam 05.05.13 в 15:02

0

Эти две части это код инструментирования и код анализа. Они находятся в одном исполняемом файле - Pin инструменте. Pin инструменты можно понимать как плагины, который позволяют модифицировать процесс генерации кода внутри Pin'a.

noam 13.05.13 в 15:31

0

Pin инструмент регистрирует callback-функции инструментирования с помощью Pin'a, который вызывает эти функции всякий раз, когда должен быть сгенерирован новый код. Эти callback-функции представляют первый компонент. Он осматривает генерируемый код, исследует его статические свойства и решает куда вставить вызовы для анализа функций.

noam 05.05.13 в 15:07

0

Функция анализа собирает данные о приложении. Pin убеждается, что все регистры сохранены и восстановлены как надо и позволяет передать аргументы в функцию.

noam 05.05.13 в 15:11

0

Pin инструмент может так же регистрировать callback-функции для уведомлений о событиях, таких как создание потока или разветвление. Эти функции обычно используются для инициализации инструментов, очистки, сбора данных.

noam 05.05.13 в 15:14

0

Замечания

noam 12.05.13 в 17:21

0

Так как Pin инструмент работает как плагин, он должен выполняться в том же адресном пространстве, что Pin и исполняемый файл. Следовательно Pintool имеет доступ ко всем данным исполняемого файла. Он так же разделяет дескрипторы файлов и другую информацию о процессе с исполняемым файлом.

noam 05.05.13 в 15:16

0

Pin и Pin инструмент контролируют программу с самой первой команды. Для файлов, скомпилированный с разделяемыми библиотеками подразумевается, что запуск динамического загрузчика и всех библиотек будет видимым для Pin инструмента.

noam 05.05.13 в 15:20

0

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

noam 12.05.13 в 17:27

0

Гранулярность инструментирования

noam 13.05.13 в 15:26

0

Как было написано выше, Pin представляет собой JIT компилятор. Инструментарий вызывается непосредственно перед тем, как код исполняется первый раз. Мы называем это инструментами трассировки.

noam 05.05.13 в 16:02

0

Инструменты трассировки позволяют Pin инструменту изучать и встраивать код в нужное время. Трассировка обычно начинается в выбранной ветке и заканчивается в безусловной, включающей вызовы функций и возвраты (returns прим. перев.) Pin гарантирует только, что трассировка начнется со входа, но выходов может быть несколько. Если ветка присоединяется в середине трассировки, то Pin строит новый маршрут с началом в этой ветке. Pin разбивает всю трассировку на базовые блоки - BBL (Basic Blocks). BBL - последовательность команд одним входом и одним выходом. Ветки в середине BBL начинают новый маршрут и, следовательно, новый BBL. Часто есть возможность вставить вызов функции для анализа для BBL, вместо функций для каждой инструкции. Сокращение числа таких вызовов делает инструментарий более эффективным.

noam 05.05.13 в 16:42

0

Заметим, что здесь BBL понимается немного в другом смысле, чем классический BBL, который вы можете найти в руководстве к компилятору. Например, расмотрим код сгенерированный для оператора switch:

noam 05.05.13 в 16:57

0

Сгенерируется код вроде того, что ниже

noam 05.05.13 в 16:58

0

В терминах классических BBL, каждая инструкция addl является отдельным BBL. Однако по мере того, как будут запускаться разные случаи, Pin будет генерировать сначала все четыре инструкции (где .L7 - вход), три инструкции (где .L6 - вход) и так далее. Это значит, что количество BBL в случае Pin вряд ли совпадет с тем, какого бы вы ожидали, если бы думали, что мы имеем BBL в классическом его виде. Здесь, например, если код попадает на .L7, то будет один BBL для случая Pin, но четыре BBL в классическом понимании.

noam 05.05.13 в 17:04

0

Pin так же разбивает BBL на другие инструкции, которых вы можете не ожидать, например (для IA-32 и Intel 64 архитектур) cpuid, popf и REP заканчивают маршрут, и следовательно сам BBL. Так как REP является префиксной инструкцией, которая часто является скрытым циклом, то если REP итерируется больше чем один раз, то все итерации после первой будут создавать BBL из одной инструкции, поэтому в этом случае вы увидите большее количество BBL, чем вы ожидаете.

noam 09.05.13 в 19:35

0

Для удобства программистов, Pin предлагает режим обработки инструкций, который позволяют инструменту изучать и обрабатывать исполняемый код по одной инструкции. Это, в общем, идентично трассировке. Как будет описано ниже, некоторые BLL и инструкции в них могут быть сгенерированы (и следовательно обработаны) несколько раз. Обработка инструкций использует API вызов INS_AddInstrumentFunction.

noam 12.05.13 в 17:38

0

Иногда может быть полезно посмотреть разные гранулярности, чем маршрут. Для этих целей Pin предлагает два дополнительных режима: инструментирование образа и инструментирование процедур. Эти режимы реализуются при помощи запросов "кэширующего" инструментирования и следовательно подвержены переполнению.

noam 13.05.13 в 15:21

0

Инструментирование образа позволяет Pin инструменту изучать и обрабатывать целый образ, IMG, когда он загружается первый раз. Pin инструмент может проходить по частям (SEC от section прим. перев.) образа, процедурам (RTN от routine прим. перев.) и инструкциям (INS от instruction прим. перев.) Обработка может быть вставлена так, чтобы она запускалась до или после запуска процедуры или инструкции. Инструменитрование образа используем API вызов IMG_AddInstrumentFunction. Инструменитрование образа зависит от символов, так как необходимо определять границы процедур, следовательно PIN_InitSymbols должна вызываться до PIN_Init.

noam 12.05.13 в 18:50

0

Инструментирование процедур позволяет Pin инструменты изучать и обрабатывать целые процедуры до того, как они вызовутся. Pin инструмент может проходить по инструкциям процедуры. Но для того, чтобы разбить инструкции на BBL не достаточно информации. Обработка может быть вставлена так, чтобы она запускалась до или после запуска процедуры или инструкции. Инструментирование процедуры может быть более эффективным, чем инструментирование образа в момент, когда в образе запущено лишь небольшое количество процедур. Инструментирование процедур использует API вызов RTN_AddInstrumentFunction. Заверешение нструментирования процедур работает не надежно в случаях когда нельзя надежно обнаружить инструкции возврата или когда имеет место хвостовая рекурсия.

noam 12.05.13 в 19:02

0

Символы

noam 09.05.13 в 19:36

0

Pin предоставляет доступ к именам функций, используя символы объектов (SYM, symbol object). Symbol object только обеспечивает информацию о символах функций в приложении. Информация о других типах символов (например символы данных), необходимо получать отдельно.

noam 09.05.13 в 19:40

0

В Windows, для этого вы можете использовать dbghelp.dll. Отметим, что использование dbghelp.dll в обрабатываемом процессе не безопасно и в некоторых случаях может являться причиной dead-lock'ов. Возможное решение - получить символы, используя разные необрабатываемые процессы.

noam 09.05.13 в 19:43

0

В Linux, libelf.so или libdwarf.so можно использовать для получения символьной информации.

noam 09.05.13 в 19:44

0

Необходимо вызывать PIN_InitSymbols, чтобы получить доступ у функции по ее имени. Смотрите SYM: Символы объектов для дополнительной информации.

noam 09.05.13 в 19:46

0

Поддержка чисел с плавающей точкой в процедурах анализа

noam 09.05.13 в 19:46

0

Нельзя использовать IARG_REG_VALUE для передачи регистра чисел с плавающей точкой в процедуры анализа в качестве аргумента.

noam 12.05.13 в 17:23

0

Обработка многопоточных приложений

noam 09.05.13 в 19:52

0

Обработка многопоточных программ требует, чтобы инструмент был потокобезопасным - доступ к данным должен быть согласован с остальными потоками. Pin пытается обеспечивать соглашение С++ программ для инструментов, но нельзя использовать интерфейсы стандартной библиотеки. Вместо этого, Pin предоставляет свой собственный API для блокировок и потоков, которые должен использовать Pin инструмент.

noam 09.05.13 в 19:58

0

Pin инструменту не нужно добавлять свои блокировки в процедуры инструментирования, потому что Pin вызывает эти процедуры, имея внутренние блокировки, называемые VM блокировками. Однако, Pin параллельно запускает функции анализа и замены, поэтому Pin инструменту может понадобиться добавить свои блокировки в эти процедуры, если они обращаются к глобальным данным.

noam 13.05.13 в 15:26

0

Pin инструменты под Linux так же должны с осторожностью вызывать функции из стандартной библиотеки из кода анализа, потому что C и C++ библиотеки, слинкованные в Pin инструменте не потоко безопасны. Некоторые простые C / C++ безопасны для вызова без блокировки, потому что их реализации по сути потоко безопасны, однако, Pin не пытается создать список безопасных функций. Если вы сомневаетесь, добавляйте блокировку вокруг библиотечных функций. В частности, значение "errno" не потоко безопасно, поэтому инструменты, которые использует его должны обеспечивать свою собственную блокировку. Отметим, что эти ограничения существуют для Unix платформ, так как библиотечные функции в Windows потоко безопасны.

noam 12.05.13 в 19:15

0

Pin предоставляет callback вызовы , когда каждый поток начинается или заканчивается (смотрите PIN_AddThreadStartFunction и PIN_AddThreadFiniFunction). Они дают удобное место для Pin инструмента чтобы размещать и управлять локальными данными потока и хранить их в локальном хранилище потока.

noam 12.05.13 в 19:19

0

Pin так же обеспечивает аргумент процедурного анализа (IARG_THREAD_ID), который передается в определенном Pin ID потока для вызывающего потока. Этот ID отличается от ID потока, который присасывается ОС, и является небольшим числом, начинающееся с 0, которое может использоваться в качестве индекса массива данных потока или в качестве блокирующего значения для пользовательских блокировок Pin. Смотрите примеры Instrumenting Threaded Applications для дополнительной информации.

noam 12.05.13 в 17:08

0

Кроме этого, Pin API обеспечивает эффективное локальное хранилище потоков (TLS), с опцией размещения нового TLS ключа и связывания его с данной деструктивной функцией. Любой поток процесса может хранить и возвращать значения в свой собственный слот, определяемый размещенным ключом. NULL является начальным значением ключа во всех потоках. Смотрите пример "Использование TLS" для дополнительной информации.

noam 12.05.13 в 17:14

0

False sharing происходит, когда разные потоки получает доступ к одной и той же строке кэша и по крайней мере одна их них на запись. Чтобы поддерживать связность памяти, компьютер должен копировать память из одного CPU кэша в другой, даже если данные на самом деле не общие. Смотрите пример "Использование TLS" для дополнительной информации.

noam 12.05.13 в 17:18

0

Как избежать deadlock'ов в многопоточных приложениях

noam 09.05.13 в 20:02

0

Так как Pin и приложение может получать и освобождать блокировку, разработчики Pin инструмента должны избегать deadlock'a приложения или Pin'a. Deadlock'и обычно происходят, когда два потока получают одну и ту же блокировку в неверном порядке. Например, поток А получает блокировку L1 и затем получает блокировку L2, пока поток B получает блокировку L2 и затем получает блокировку L1. Это приведет к блокировке, если поток A будет держать блокировку L1 и ждать L2, в то время как поток B будет держать блокировку L2 и ждать блокировку L1. Чтобы избежать таких deadlock'ов, Pin создает иерархию взятия блокировок. Pin обычно получает свои собственные блокировки до того, как инструмент получит какую либо блокировку (например при помощи GetLock()). Кроме того, мы предполагаем, что приложение может получать блокировки на вершине этой иерархии (т.е. до того как Pin получит свои внутренние блокировки). Следующий график иллюстрирует данную иерархию:

noam 12.05.13 в 19:31

0

Блокировки приложения -> Внутренние блокировки Pin'a -> Блокировки инструмента

noam 09.05.13 в 19:50

0

Разработчики Pin инструментов должны проектировать их так, чтобы они никогда не нарушали эту иерархию блокировок, и они могут это делать, следуя этим базовым советам:

noam 09.05.13 в 19:52

0

Если инструмент получает какие либо блокировки из Pin callback'a, он должен освободить их до возвращения из этого callbacka'a. Удержание блокировки означает нарушения иерархии по отношению к внутренним блокировкам Pin'a.

noam 12.05.13 в 19:57

0

Если инструмент получает какие либо блокировки из процедуры анализа, он должен освободить их до возвращения из процедуры анализа. Удержание блокировки означает нарушения иерархии по отношению к внутренним блокировкам Pin'a и к другим блокировкам, используемым для инструментирования приложения.

noam 12.05.13 в 19:58

0
Минутку...

Следующая страница →