Ответ 1
Я пишу инструменты, которые выполняют инструменты. Итак, вот что я думаю.
-
Перезапись DLL. Это то, что делают такие инструменты, как Purify и Quantify. В предыдущем ответе на этот вопрос говорилось, что они послекомпилируют/связывают инструмент. Это неверно. Очистить и квантифицировать инструмент DLL в первый раз, когда он выполняется после цикла компиляции/ссылки, затем кэшировать результат, чтобы его можно было использовать быстрее в следующий раз. Для больших приложений профилирование DLL может занять много времени. Это также проблематично - в компании, с которой я работал в период с 1998 по 2000 год, у нас было большое 2-миллионное линейное приложение, которое потребовало бы 4 часов на инструмент, а 2 из DLL случайно разбились бы во время инструментария, и если либо вы не смогли бы удалить оба они, затем начните.
-
На месте приборы. Это похоже на переписывание DLL, за исключением того, что DLL не изменяется и изображение на диске остается нетронутым. Функции DLL соответствующим образом подключаются к задаче, требуемой при первой загрузке DLL (либо во время запуска, либо после вызова LoadLibrary (Ex). В библиотеке Microsoft Detours вы можете увидеть методы, подобные этому.
-
На лету. Как и на месте, но только на самом деле инструменты метода при первом запуске метода. Это сложнее, чем на месте, и откладывает штраф за инструментальную обработку до тех пор, пока первый метод не встретится. В зависимости от того, что вы делаете, это может быть хорошо или плохо.
-
Инструментарий промежуточного языка. Это то, что часто делается с Java и .Net-языками (C ~, VB.Net, F # и т.д.). Язык компилируется на промежуточный язык, который затем выполняется виртуальной машиной. Виртуальная машина предоставляет интерфейс (JVMTI для Java, ICorProfiler (2) для .Net), который позволяет вам отслеживать, что делает виртуальная машина. Некоторые из этих параметров позволяют вам изменить промежуточный язык непосредственно перед его компиляцией в исполняемые инструкции.
-
Промежуточное инструментальное оборудование посредством отражения. Java и .Net предоставляют API-интерфейсы отражения, которые позволяют обнаруживать метаданные о методах. Используя эти данные, вы можете создавать новые методы "на лету" и применять существующие методы так же, как и ранее упомянутые инструменты промежуточного языка.
-
Компиляция времени. Этот метод используется во время компиляции для вставки соответствующих инструкций в приложение во время компиляции. Не часто используемая функция профилирования Visual Studio предоставляет эту функцию. Требуется полная перестройка и ссылка.
-
Инструментарий исходного кода. Этот метод используется для изменения исходного кода для вставки соответствующего кода (обычно условно скомпилированного, чтобы вы могли отключить его).
-
Инструмент времени соединения. Этот метод действительно полезен только для замены распределителей памяти по умолчанию на распределители трассировки. Ранним примером этого был детектор утечки памяти Sentinel на Solaris/HP в начале 1990-х годов.
Различные методы измерения на месте и на лету чреваты опасностью, так как очень сложно безопасно остановить все потоки и изменить код, не рискуя потребовать вызова API, который может захотеть получить доступ к блокировке который удерживается нитью, которую вы только что приостановили, - вы не хотите этого делать, вы получите тупик. Вы также должны проверить, выполняет ли какой-либо из других потоков этот метод, потому что если вы не можете его изменить.
Методы инструментов на основе виртуальной машины гораздо проще использовать, так как виртуальная машина гарантирует, что вы можете безопасно модифицировать код в этой точке.
- (EDIT - этот элемент добавлен позже). Это включало изменение таблицы импорта данных для функций, связанных с другими DLL/Shared Libraries. Этот тип приборов, вероятно, является самым простым методом для работы, вам не нужно знать, как разбирать и модифицировать существующие двоичные файлы, или делать то же самое с кодами операций виртуальной машины. Вы просто исправляете таблицу импорта со своим собственным адресом функции и вызываете реальную функцию с вашего крючка. Используется во многих коммерческих и открытых инструментах.
Я думаю, что я их охватил, надеюсь, что это поможет.