Выбрать главу

if x then

trace(1)

end if

Аналогично, вы можете выключить (деактивировать) трассировку командой trace(0). Вы можете также выключить трассировку интерактивно, с клавиатуры, нажав клавишу 'q'. Не забывайте, что метакоманда with trace должна быть записана вне тела подпрограммы, т.е. на высшем уровне кода, в то время как команды активации trace() можно писать и внутри подпрограмм, и вне их.

Иногда вам будет необходимо активировать трассировку изнутри типа. Предположим, что вы запускаете программу, а она останавливается с файлом ex.err, из которого следует, что одна из ваших переменных приняла некоторое странное значение, величина которого хотя и законна, но вас удивляет, как это вообще могло произойти. Просто создайте тип для этой переменной, в котором команда trace(1) выполняется, если присваиваемая переменной величина принимает то странное значение, которое так вас заинтересовало, то есть,

type positive_int(integer x)

if x = 99 then

trace(1) -- как это может быть???

return 1 -- продолжать

else

return x 0

end if

end type

Когда positive_int() завершится, вы увидите именно ту команду, которая присвоила вашей переменной странное значение, и тогда сможете проверить величины других переменных, вовлечённых в это действо. Вы сможете также проверить выходной экран вашей программы, чтобы увидеть, что происходит именно в этот момент. Если вы определите positive_int() так, чтобы для странной величины (99) выдавался 0 вместо 1, это вызовет остановку программы с распечаткой диагностической информации в файл ex.err.

3.1.1 Экран трассировки

Когда команды trace(1) или trace(2) исполняются интерпретатором, главный экран вашей программы сохраняется в памяти и на отображение выводится экран трассировки. На нём показан текст вашей программы; команда, которая подлежит исполнению на следующем шаге, выделена в тексте; одновременно в обычном цвете показаны несколько предшествующих и последующих команд. Несколько строк внизу экрана оставлены для отображения имён переменных и их значений. В самой верхней строке (меню) показаны команды, которые вы можете в данной точке ввести с клавиатуры:

F1

-

отобразить главный экран программы - для просмотра той информации, которую выводит ваша программа

F2

-

вернуться на экран трассировки. Нажмите эту клавишу, если после просмотра главного экрана программы вам необходимо снова вывести экран трассировки.

Enter

-

исполнить только выделенную в тексте программы команду

стрелка-вниз

-

продолжить исполнение и прервать его, когда придёт время исполнить команду, следующую в листинге исходного кода высшего уровня за данной командой. Этот пункт меню позволяет вам пропускать трассировку внутренних команд подпрограмм, а также останавливаться на первой команде, следующей за окончанием циклов for и while, если нет необходимости смотреть на все подряд шаги циклов.

?

-

отобразить величину переменной. После нажатия на клавишу ? вы будете приглашены ко вводу имени переменной. Многие переменные отображаются для вас автоматически по мере присваивания им очередных величин. Если переменная в данный момент не видна, или видна только частично, вы можете вызвать её на отображение отдельно. Длинные ряды ограничиваются одной строкой экрана, но когда вы вызываете ряд на отображение, экран очистится и вы сможете прокрутить ряд, выведенный на отображение с помощью pretty_print(). Затем отображение вернётся в обычный режим с одной строкой под переменную. Переменные, ещё не объявленные в данной точке программы, не могут быть показаны. Переменные, которые ещё не инициализированы, после имени обозначаются как "". Отображаются только переменные, но не общие выражения. По мере вашего продвижения по программе, система обновляет все величины, выведенные на экран. Периодически она будет удалять с экрана переменные, сцена которых закончилась или которые довольно долго (в сравнении с быстроменяющимися) не изменяли своего значения.

q

-

прервать трассировку и возобновить обычное исполнение. Трассировка восстановится, когда интерпретатор встретит очередную команду trace(1) и исполнит её.

Q

-

прервать трассировку и позволить программе исполняться в обычном порядке до самого завершения. Команды trace() интерпретатором будут игнорироваться.

!

-

команда немедленно прерывает вашу программу. Трасса недавних последних команд программы и распечатка величин переменных выводятся в файл ex.err.

По мере трассировки вашей программы, имена переменных и их величины будут автоматически появляться в нижней части экрана. Когда переменной присвоено новое значение, вы увидите её имя и новую величину в нижней строке. Отображаемая величина переменной всегда соответствует её текущему значению. Частные переменные автоматически стираются с экрана, как только подпрограмма закончилась. Когда область, выделенная для показа переменных, заполняется, наиболее давние переменные удаляются с экрана, чтобы освободить место для новых. Величины элементов в длинных рядах не отображаются, если уходили бы на экране за пределы 80-ой колонки.

Для вашего удобства, числа, которые находятся в диапазоне кодов символов (32-127) таблицы ASCII, отображаются вместе с собственно символом ASCII. Символ ASCII подсвечивается другим цветом (или забирается в кавычки на монохромном дисплее). Такое преобразование делается для всех переменных, так как Euphoria "не знает", о чём вы на самом деле думаете, о числах или о символах ASCII. Символы ASCII (в кавычках) также выводятся и в файл ex.err. Это дублирование несколько переполняет экран, но информация ASCII часто бывает очень полезной.

Экран трассировки адаптируется к тому графическому режиму, который действует для главного экрана программы. Адаптация делает переключение между экранами более быстрым и лёгким.

Когда по ходу дела в трассируемой программе требуется ввод данных с клавиатуры, открывается главный экран, чтобы дать вам возможность произвести ввод данных так, как вы это обычно делаете. Этот приём хорошо работает с подпрограммой gets(), обеспечивающей ввод (чтение одной строки). А когда задействована подпрограмма get_key() (быстрый опрос клавиатуры), вам даётся 8 секунд, чтобы нажать необходимую клавишу, и если клавиша не нажата, считается, что по данному вызову get_key() ввода не последовало. Этот приём даёт вам возможность проверить случай, когда ввод был, и случай, когда ввода по get_key() не было.

3.1.2 Файл трассировки

Когда ваша программа вызывает trace(3), активируется трассировка в файл. В текущем каталоге открывается файл ctrace.out. В нём записываются последние 500 команд Euphoria, которые выполнены по вашей программе. Здесь работает круговой буфер, в котором содержится максимум 500 команд. Когда достигнут конец ctrace.out, следующая исполненная команда записывается в начале файла. Самая последняя исполненная команда всегда сопровождается строкой "=== THE END ===". Поскольку буфер круговой, запись о последней исполненной команде может появиться в любом месте файла ctrace.out. Команда, записанная перед строкой "=== THE END ===" в уже очень длинном файле, является 500-ой в буфере, последней.

Данная форма трассировки поддержана и интерпретатором, и транслятором с Euphoria на Си. Она бывает особенно полезна, когда случается аврийная остановка на машинном уровне, препятствующая Euphoria в записи обычного диагностического файла ex.err. Взглянув на последнюю перед аварией выполненную команду, вы можете составить обоснованное предположение о причине аварии. Возможно, этой последней командой был вызов poke() по незаконному адресу в памяти. Возможно, это был вызов подпрограммы Си. В некоторых случаях это может быть сигналом о наличии ошибки в собственно интерпретаторе или трансляторе.