Введение в Debugger Scripting

Скрипты необходимы чтобы автоматизировать действия, производимые в отладчике вручную. К примеру, можно совершить 1000 шагов в цикле, изменять и получать значения переменных. Кроме того данный механизм позволит вам выполнять следующие действия:

  • Изменять ход выполнения программы (путем изменения переменных)
  • Анализировать значения переменных и ход выполнения программы
  • Создавать журналы выполнения программы (трассировки)
  • Создавать точки наблюдения и остановок, в зависимости от условий

Скрипты используют интерфейс отладчика и запускаются на его стороне. Они не могу непосредственно изменять код программы, но могут повлиять на ход его выполнения. Окно скриптов в отладчике:

  1. Редактор скрипта, как видно скрипт представляет собой класс с методами, через которые получает доступ к отладчику.
  2. Триггер – определяет событие, при котором будет вызван скрипт. Скрипт может быть вызван напрямую (Debugger Simple Step – execute directly), либо из точки наблюдения или остановки.
  3. В этой области как не трудно догадаться скрипт можно сохранить (как Z программу, либо отдельным файлом)
  4. С помощью кнопки Start Script происходит выполнение скрипта
  5. Script Wizard предоставляет доступ к заранее подготовленным шаблонам – использующим возможности интерфейса отладчика, например с его помощью можно вставить метод чтения значений переменной.
  6. Если вы создаете трассировки, то их список можно увидеть на вкладке – Traces Files. Список трассировок можно так же посмотреть отдельно в транзакции SAS, из нее можно редактировать и сохранять скрипты. Трассировки могут быть следующих видов: Statement Trace (Записывает информацию о текущей строке исходного кода, которая обрабатывается в скрипте), Trace of the Call Hierarchy (Запись иерархии вызовов), User Specific Trace (Определенный пользователем вид).

Далее рассмотрим созданный локальный класс скрипта. Скрипт наследуется от глобального класса — CL_TPDA_SCRIPT_CLASS_SUPER. По умолчанию для него создаются следующие методы:

  1. Prologue – техническая инициализация скрипта. Когда скрипт запускается, отладчик сначала выполняет данный метод. В реализации супер класса данного метода происходит обновление информации об исходном коде программы (super->abap_source), если вам не нужна данная информация, вы можете ускорить выполнение скрипта, закомментировав вызов метода prologue супер класса.
  2. Init – инициализация скрипта. Вызов происходит после prologue только один раз, Вы можете использовать его для инициализации внутренних данных либо для запроса у пользователя информации необходимой для скрипта.
  3. Script – метод вызывающийся при каждом срабатывании триггера, или прямом выполнении скрипта. В данный метод передается параметр p_trigger – обозначающий тип триггера, который его запустил. Кроме того у него есть два исключения, cx_tpda_stop_scripting_request – вызвав данное исключение вы прекратите срабатывание скрипта по данному триггеру, cx_tpda_script_continue – продолжает выполнение работы скрипта. Для того чтобы позволить пользователю выбрать хочет он продолжать работу скрипта далее или нет используйте метод —  me->break( ).
  4. End – конец выполнения скрипта. Срабатывает когда пользователь отменяет работу скрипта, либо когда он сам ее завершает.

Супер класс поддерживает следующие сервисы:

  • abap_source – данные об исходном коде программы, например получить имя программы можно следующим образом — currr_prog = abap_source->program( )
  • bp – работа с точками остановок
  • wp – работа с точками наблюдения
  • debugger_control – позволяет управлять отладчиком на уровне шага, перейти на шаг вперед (назад)
  • dynpro – информация о экранах
  • specials – прочая системная информация (Работа с памятью, вызов commit work и пр.)

Автоматизация рутинных действий

Допустим, есть следующая программа:

Как видно из кода, переменной gv_rc всегда будет присваиваться значение true, таким образом, чтобы пройти весь цикл нам необходимо в каждой итерации цикла подменять значение переменной, что само по себе накладно (для 1000 итераций J). Воспользуемся скриптами. Запустите программу в отладке и перейдите на закладку Scripts. В качестве триггера выберите Breakboint Reached, создайте точку остановки для процедуры Test.

В момент, когда процедура будет запущена, сработает метод Script. Нам необходимо чтобы при этом отладчик вышел из процедуры и подменил значение переменной gv_rc. Как уже упоминалось выше для контроля над процессом отладки в классе super, есть подкласс – debugger_controller. С помощью его метода – debug_step мы можем выполнить нужный нам шаг, в качестве команды задать — CL_TPDA_SCRIPT_DEBUGGER_CTRL=>debug_step_over. Далее с помощью помощника выберем изменение значений переменной. В итоге получиться следующий код:

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

Интерактивные скрипты

Допустим, необходимо чтобы при смене ABAP стека каждый раз, когда мы переходим в определенную программу, вызывался скрипт, но при этом мы хотим сделать скрипт более универсальным, т.е. имя программы необходимо задавать при его инициализации. Для запроса имени программы в методе init используем ФМ POPUP_GET_VALUES, имя программы будем хранить в глобальной переменной нашего класса. Поставим триггер на точку прерывания при смене ABAP стека.

В методе script сравним имя программы в текущем контексте отладчика с именем указанным при инициализации, если оно совпало, вызовем прерывание скрипта. Изменим предыдущую программу (создадим дополнительно новую – ZTMP3 с такой же процедурой, которая описана выше):

Исходный код скрипта будет выглядеть следующим образом:

После запуска скрипта, его остановка произойдет, как только мы изменим ABAP стек, вызвав процедуру из другой программы.

Динамическое создание точек прерывания и наблюдения

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

Исходный код скрипта для прерывания в момент чтения внутренней таблицы можно загрузить из стандартного подготовленного SAP скрипта — RSTPDA_SCRIPT_BP_READ_TAB. Его исходный код:

Данный скрипт по умолчанию загружает точку остановки на моменте вызова READ TABLE для внутренних таблиц.

Использование трассировок

Как говорилось выше можно использовать разные виды трассировок. Следующий пример покажет, как использовать — Statement Trace. Задача: найти все вызовы проверки полномочий в стандартной транзакции – ME23N (во время запуска).

 

  • Заходим в SE93, указываем ME23n, жмем – отладку (Тест – отладка).
  • Переходим на вкладку скрипт, используя заранее подготовленный скрипт загрузим — RSTPDA_SCRIPT_STATEMENT_TRACE
  • В качестве триггера создадим точку на вызов — AUTHORITY-CHECK
  • Запускаем скрипт, жмем – Continue
  • После запуска транзакции (нас интересовал только запуск) в командной строке набираем /h и жмем F3 – вылетит отладчик в котором необходимо завершить работу скрипта – EXIT SCRIPT.
  • Запускаем транзакцию SAS (либо прямо в отладчике через закладку трассировок) – смотрим трассировку.

В итоге получится что-то вроде:

Добавление в журнал трассировок своих данных (User Specific Trace).

Задача: есть таблица с данными ОЗМ необходимо в журнал затащить все записи, у которых БЕИ отличается от M3. В журнале должен быть номер материала и его ЕИ. Пример программы:

  1. Создаем точку наблюдения для переменной gt_mara-meins <> ‘M3’
  2. С помощью метода подкласса trace – add_custom_info добавляем свои данные.
  3. Метод script будет иметь следующий вид:

После этого если у вас были такие материалы, они отобразятся в трассировке: