Next: , Previous: , Up: Top   [Contents][Index]

39 Отладка


Next: , Up: Отладка   [Contents][Index]

39.1 Отладка на уровне исходного кода

Maxima имеет отладчик исходного кода. Пользователь может определить в функции точку останова и и продолжить выполнение с этой точки строка за строкой. При этом возможно анализировать стек вызовов и переменные, имеющие значение на данном уровне.

Команда :help, или просто :h, выводит список команд отладчика. (Команды могут быть сокращены, если сокращение однозначно. Если оно неоднозначно, то будет выведен список альтернатив.) В отладчике пользователь может также использовать обычные команды Maxima для исследования, определения и манипулирования переменными и выражениями.

Точка останова задается командой :br в командной строке Maxima. В отладчике, пользователь может продвигаться по одной строке за раз с помощью команды :n (“next”). Команда :bt (“backtrace”) выводит список кадров стека. Команда :r (“resume”) завершает отладчик и продолжает выполнение программы. Данные команды проиллюстрированы в следующем примере.

(%i1) load ("/tmp/foobar.mac");

(%o1)                           /tmp/foobar.mac

(%i2) :br foo
Turning on debugging debugmode(true)
Bkpt 0 for foo (in /tmp/foobar.mac line 1) 

(%i2) bar (2,3);
Bkpt 0:(foobar.mac 1)
/tmp/foobar.mac:1::

(dbm:1) :bt                        <-- :bt выводим обратную трассировку вызовов
#0: foo(y=5)(foobar.mac line 1)
#1: bar(x=2,y=3)(foobar.mac line 9)

(dbm:1) :n                         <-- :n продвигаем выполнение на одну строку
(foobar.mac 2)
/tmp/foobar.mac:2::

(dbm:1) :n                         <-- :n продвигаем выполнение на одну строку
(foobar.mac 3)
/tmp/foobar.mac:3::

(dbm:1) u;                         <-- Исследуем знасение переменной u
28

(dbm:1) u: 33;                     <-- Устанавливаем значение u равным 33
33

(dbm:1) :r                         <-- :r to возобновляем выполнение программы

(%o2)                                1094

Содержимое файла /tmp/foobar.mac:

foo(y) := block ([u:y^2],
  u: u+3,
  u: u^2,
  u);
 
bar(x,y) := (
  x: x+2,
  y: y+2,
  x: foo(y),
  x+y);

Использование Отладчика в Редакторе Emacs

Если пользователь выполняет программу в командном окне отладчика (dbl) редактора GNU emacs или в графической оболочке Xmaxima, то при достижении точки останова в другой части окна будет показан участок исходного кода с текущей строкой, выделенной либо красным цветом, либо маленькой стрелкой. Пользователь может продолжить выполнение программы построчно, нажимая M-n (Alt-n).

Для использования в Emacs отладчика dbl требуется файл dbl.el, расположенный в директории elisp. Убедитесь, что файлы elisp установлены или добавьте директорию elisp программы Maxima к пути: например, добавте следующие строки к файлу .emacs или файлу site-init.el

(setq load-path (cons "/usr/share/maxima/5.9.1/emacs" load-path))
(autoload 'dbl "dbl")

После этого при вводе

M-x dbl

в emacs должно открываться командное окно, в котором можно выполнять программы, например, Maxima, gcl, gdb и т.д. Это командное окно “знает” об отладке исходного кода, который открыт в другом окне редактора.

Пользователь может установить точку останова в определенной строке кода, нажав на C-x space. При этом производится анализ: в какой функции находится данная строка и на какой по порядку строке этой функции стоит курсор. Если курсор расположен, скажем, на строке 2 функции foo, тогда в командном окно будет введена команда “:br foo 2”, которая задает точку останова на второй строке функции foo. Для того, чтобы все это работало необходимо, чтобы в окне файла foobar.mac был включен режим maxima-mode.el. Существуют еще дополнительные команды, доступные в таком окне, такие как вычисление функций Maxima при нажатии Alt-Control-x.


Next: , Previous: , Up: Отладка   [Contents][Index]

39.2 Специальные команды

Специальные команды, это ключевые слова, которые не интерпретируются Maxima как обычные выражения. Специальные команды вводятся в командной строке Maxima или отладчика, но не в точке останова. Все специальные команды начинаются с двоеточия ’:’. Например, для вычисления Lisp формы можно ввести :lisp с последующей формой.

(%i1) :lisp (+ 2 3) 
5

Число параметров зависит от конкретной команды. Кроме того, не обязательно вводить всю команду целиком, достаточно ввести столько, чтобы сделать команду однозначно определенной среди всех ключевых слов. Таким образом, для :break достаточно ввести :br.

Специальные команды перечислены ниже:

:break F n

Задает точку останова в функции F на строке номер n от ее начала. Если F является строкой, тогда он рассматривается как файл и смещение n отсчитывается от начала этого файла. Смещение является необязательным. Если оно не указано, то предполагается равным нулю (первая строка функции или файла).

:bt

Выводит обратную трассировку кадров стека

:continue

Продолжает вычисление

:delete

Удаляет заданную точку останова или все, если ни одна не задана

:disable

Деактивирует заданную точку останова или все, если ни одна не задана

:enable

Активирует заданную точку останова или все, если ни одна не задана

:frame n

Выводит кадр стека номер n или текущий кадр, если номер не указан

:help

Печатает справку по указанной команде или по всем если ни одна не задана

:info

Печатает информацию об элементе

:lisp some-form

Вычисляет some-form в качестве Lisp формы

:lisp-quiet some-form

Вычисляет Lisp форму some-form без вывода результата

:next

Как :step, но :next пропускает вызовы функций

:quit

Выход из текущего уровня отладчика без завершение вычислений

:resume

Продолжает вычисление

:step

Продолжает вычисление до достижения новой строки

:top

Возвращает на уровень командного приглашения Maxima с любого уровня отладчика без завершения вычислений


Previous: , Up: Отладка   [Contents][Index]

39.3 Функции и переменные для отладки

Управляющая переменная: refcheck

Значение по умолчанию: false

Если refcheck равна true, то Maxima печатает сообщение каждый раз как имеющая значение переменная используется в вычислении первый раз.

Управляющая переменная: setcheck

Значение по умолчанию: false

Если setcheck равно списку переменных (возможно с индексом), то Maxima печатает сообщение всякий раз как переменным, или переменным с индексом, присваивается значение при помощи обычного оператора присваивания :, или оператора присваивания ::, или при связывании параметров функций, но не при определении функций := или макросов ::=. Сообщение содержит имя переменной и присваиваемое значение.

Переменной setcheck может быть присвоено значение all или true, что подразумевает все переменные.

Каждое присваивание setcheck устанавливает новый список контролируемых переменных и все переменные, которые ранее были в списке setcheck, забываются.

Переменные, присваиваемые setcheck должны быть экранированы, иначе они могут быть вычислены. Например, если переменные x, y и z уже имеют значения, тогда

setcheck: ['x, 'y, 'z]$

устанавливает контроль присваивания для этих переменных.

Сообщение не выводится, если переменной, включенной в список setcheck, присваивается значение равное ей самой, например, X: 'X.

Управляющая переменная: setcheckbreak

Значение по умолчанию: false

Если setcheckbreak равно true, то Maxima генерирует прерывание всякий раз как переменной из списка setcheck присваивается новое значение. Прерывание случается до присваивания нового значения. В этот момент, переменная setval содержит новое значение переменной. Таким образом, возможно присвоить переменной другое значение путем присваивания его переменной setval.

См. также setcheck и setval.

Системная переменная: setval

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

См. также setcheck и setcheckbreak.

Функция: timer (f_1, ..., f_n)
Функция: timer (all)
Функция: timer ()

Добавляет функции f_1, ..., f_n к списку функций, для которых собирается статистика тайминга. Последовательные вызовы timer(f)$ timer(g)$ сначала добавляют к списку f а затем g, т.е. список пополняется от одного вызова timer к другому.

timer(all) добавляет все пользовательские функции, которые определяются глобальной переменной functions, к списку контролируемых функций.

Без аргументов, timer возвращает список контролируемых функций.

Maxima сохраняет информацию о времени выполнения контролируемых функций. Функция timer_info возвращает статистику тайминга, включающую: среднее время выполнения, число вызовов и полное время выполнения. Функция untimer удаляет функцию из списка контролируемых функций.

timer не вычисляет свои аргументы. Команды f(x) := x^2$ g:f$ timer(g)$ не добавят f к списку тайминг-контроля.

Если действует трассировка trace(f), то timer(f) не работает, т.к. trace и timer не могут действовать одновременно.

См. также timer_devalue.

Функция: untimer (f_1, ..., f_n)
Функция: untimer ()

Удаляет функции f_1, ..., f_n из списка тайминг-контроля.

Без аргументов, untimer удаляет все функции из списка тайминг-контроля.

После выполнения untimer (f), функция timer_info (f) продолжает содержать ранее собранную статистику, хотя timer_info() (без аргументов) не возвращает информацию о функциях, которые на данный момент не включены в список тайминг-контроля. Вызов timer (f) обнуляет всю предыдущую статистику и снова добавляет f к списку тайминг-контроля.

Управляющая переменная: timer_devalue

Значение по умолчанию: false

Если timer_devalue равно true, то Maxima вычитает из статистики контролируемой функции время выполнения других контролируемых функций. В противном случае, статистика каждой функции включает время, затраченное на выполнение других функций. Заметим, что время, затраченное на выполнение неконтролируемых функций, не вычитается из общего времени.

См. также timer и timer_info.

Функция: timer_info (f_1, ..., f_n)
Функция: timer_info ()

Для функций f_1, ..., f_n, возвращает матрицу, содержащую информацию о тайминге каждой из функций. Без аргументов, timer_info возвращает информацию для всех контролируемых функций.

Матрица, возвращаемая timer_info, содержит: имя функции, среднее время вызова функции, число вызовов, общее время и gctime, что обозначает "время сборки мусора" в Macsyma, но сейчас это время всегда равно нулю.

Данные, сообщаемые timer_info, могут быть получены другим способом при помощи функции get:

get(f, 'calls);  get(f, 'runtime);  get(f, 'gctime);

См. также timer.

Функция: trace (f_1, ..., f_n)
Функция: trace (all)
Функция: trace ()

Устанавливает трассировку для функций f_1, ..., f_n, т.е. Maxima будет печатать отладочную информацию при каждом вызове любой из этих функций. Последовательные вызовы trace(f)$ trace(g)$ сначала включает трассировку f а затем трассировку g, т.е. список трассируемых функций пополняется от одного вызова trace к другому.

trace(all) включает трассировку для всех пользовательских функций, которые определяются глобальной переменной functions.

Без аргументов, trace возвращает список всех трассируемых функций.

Функция untrace отменяет трассировку. См. также trace_options.

Функция trace не вычисляет свои аргументы. Команды f(x) := x^2$ g:f$ trace(g)$ не добавят f к списку трассируемых функций.

Если функция переопределяется, то она удаляется из списка трассируемых функций. Т.е. после timer(f)$ f(x) := x^2$, функция f трассироваться не будет.

Если действует timer (f), то trace (f) не работает; т.к. trace и timer не могут действовать одновременно.

Функция: trace_options (f, option_1, ..., option_n)
Функция: trace_options (f)

Устанавливает опции трассировки для функции f. Любые предыдущие опции переопределяются. trace_options (f, ...) не действует если не включена трассировка trace (f) (либо до, либо после вызова trace_options).

trace_options (f) возвращает все опции в значение "по умолчанию".

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

Опции трассировки могут задаваться двумя способами. Одно ключевое слово включает соответствующую опцию безусловно. Заметим, что для включения опции foo не следует указывать foo: true, кроме того, опции не надо экранировать. Ключевое слово с предикатом включает опцию условно в зависимости от значения предиката.

Существуют следующие аргументы предиката [level, direction, function, item], где level есть уровень рекурсии; direction есть либо enter, либо exit; function есть имя функции; и item есть список аргументов (при входе) или возвращаемое значение (при выходе).

Пример применения безусловных опций трассировки:

(%i1) ff(n) := if equal(n, 0) then 1 else n * ff(n - 1)$

(%i2) trace (ff)$

(%i3) trace_options (ff, lisp_print, break)$

(%i4) ff(3);

Ниже, та же функция условной опцией трассировки break:

(%i5) trace_options (ff, break(pp))$

(%i6) pp (level, direction, function, item) := block (print (item),
    return (function = 'ff and level = 3 and direction = exit))$

(%i7) ff(6);
Функция: untrace (f_1, ..., f_n)
Функция: untrace ()

Отменяет трассировку функций f_1, ..., f_n, установленную ранее при помощи trace. Без аргументов, untrace отменяет трассировку всех функций.

Функция untrace возвращает список функций, для которых была отменена трассировка.


Previous: , Up: Отладка   [Contents][Index]