Модуль StackUnit

Вернуться к оглавлению

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

Компонент разрабатывался для Delphi 5, но работает так же и в Delphi 6, и должен работать в Delphi 7. В более поздних версиях Delphi и его клонов не тестировался.

Подробное описание

В отличие от функции CrackStack в модуле utPhotoExc, сопоставляющей адреса возвратов из кадров возврата в программном стеке именам функций, сохранённым при линковке программы в файле "имя-программы".map, данный вариант предполагает модификацию всех функций программы таким образом, что в начале каждой функции вызывается специальная функция этого модуля (с именем enter) и ей передаётся при этом имя вызванной функции.

Это не означает, однако, что необходимо вручную модифицировать все свои функции таким образом, чтобы добавить обращение к этой функции в начале каждой функции или процедуры. В теле модуля StackUnit реализована функция ModifySources_AddingEnterCall(directory: String), которую достаточно вызвать один раз в начале работы программы, чтобы в начале каждого запуска программы были проверены все новые функции и добавлены для них все вызовы. В качестве параметра при этом следует передать путь, по которому лежат модули (файлы с расширением .PAS), которые следует просмотреть и модифицировать. Директория обрабатывается нерекурсивно, и если модули расположены в разных папках, то для каждой папки нужен свой отдельеый вызов процедуры.

Предусмотрена возможность предотвратить проверку на необходимость вставки обращения к enter в тех случаях, когда это необходимо: достаточно "неправильно" оформить тело процедуры, например, оставить слово procedure в отдельной строке. Или, добавить комментарий в строку, содержащую begin, начинающий тело процедуры. Если комментарий присутствует в строке implementation, начинающей секцию кода, то для всего модуля не будут выполняться проверки на добавление вызовов функции enter. Так сделано в самом модуле StackUnit и в модуле utPhotoExc (во избежание рекурсии).

Имеется возможность удалить все обращения к функции enter во всех модулях директории, простой установкой символа условной компиляции REMOVE_ENTRY_CALLS и перекомпиляцией исходного кода (Build), после чего достаточно запустить перекомпилированную программу однократно.

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

Предусмотрена работа максимум с двумя потоками. Для того, чтобы стек накапливался корректно, необходимо в начале работы каждого потока вызвать процедуру DefineThreadStack с индексом потока. Параметр 0 обычно соответствует главному потоку, 1 - дополнительному. Вообще, вызов DefineThreadStack( 0 ) выполняется при инициализации модуля, так что в случае однопоточного приложения вообще ничего делать не нужно.


(C) by Vladimir Kladov, 2000-2010