19.1.11 Внутреннее устройство отладчика

В этом разделе описаны функции и переменные, используемые внутри отладчика.

Переменная: debugger

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

Первый аргумент, который Lisp передаёт этой функции, указывает причину её вызова. Соглашение об аргументах подробно описано в описании debug (см. Вызов отладчика).

Функция: backtrace

Эта функция выводит трассировку активных в данный момент вызовов функций Lisp. Трассировка идентична той, которую debug показал бы в буфере *Backtrace*. Возвращаемое значение всегда nil.

В следующем примере выражение Lisp явно вызывает backtrace. Это выводит обратную трассировку в поток standard-output, которым в данном случае является буфер ‘backtrace-output’.

Каждая строка обратной трассировки представляет один вызов функции. Строка показывает функцию, за которой следует список значений аргументов функции, если все они известны; если они всё ещё вычисляются, строка состоит из списка, содержащего функцию и её невычисленные аргументы. Длинные списки или глубоко вложенные структуры могут быть сокращены.

(with-output-to-temp-buffer "backtrace-output"
  (let ((var 1))
    (save-excursion
      (setq var (eval '(progn
                         (1+ var)
                         (list 'testing (backtrace))))))))

     ⇒ (testing nil)

----------- Буфер: backtrace-output ------------
  backtrace()
  (list 'testing (backtrace))
  (progn ...)
  eval((progn (1+ var) (list 'testing (backtrace))))
  (setq ...)
  (save-excursion ...)
  (let ...)
  (with-output-to-temp-buffer ...)
  eval((with-output-to-temp-buffer ...))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp)
----------- Буфер: backtrace-output ------------
Пользовательская опция: debugger-stack-frame-as-list

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

При ненулевом значении debugger-stack-frame-as-list приведённый выше пример выглядел бы следующим образом:

----------- Буфер: backtrace-output ------------
  (backtrace)
  (list 'testing (backtrace))
  (progn ...)
  (eval (progn (1+ var) (list 'testing (backtrace))))
  (setq ...)
  (save-excursion ...)
  (let ...)
  (with-output-to-temp-buffer ...)
  (eval (with-output-to-temp-buffer ...))
  (eval-last-sexp-1 nil)
  (eval-last-sexp nil)
  (call-interactively eval-last-sexp)
----------- Буфер: backtrace-output ------------
Переменная: debug-on-next-call

Если эта переменная не равна nil, это означает, что перед следующим eval, apply или funcall следует вызвать отладчик. Вход в отладчик устанавливает debug-on-next-call в nil.

Команда d в отладчике работает путём установки этой переменной.

Функция: backtrace-debug level flag

Эта функция устанавливает флаг debug-on-exit для кадра стека level уровней ниже по стеку, присваивая ему значение flag. Если flag не равен nil, это вызовет вход в отладчик при последующем выходе из этого кадра. Даже нелокальный выход через этот кадр приведёт к входу в отладчик.

Эта функция используется только отладчиком.

Переменная: command-debug-status

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

Преимущество использования этой переменной вместо обычной глобальной переменной в том, что данные никогда не переносятся на последующий вызов команды.

Эта переменная устарела и будет удалена в будущих версиях.

Функция: backtrace-frame frame-number &optional base

Функция backtrace-frame предназначена для использования в Lisp-отладчиках. Она возвращает информацию о том, какие вычисления происходят в кадре стека frame-number уровней ниже.

Если в этом кадре аргументы ещё не вычислены или это специальная форма, возвращается значение (nil function arg-forms…).

Если в этом кадре аргументы уже вычислены и его функция вызвана, возвращаемое значение — (t function arg-values…).

В возвращаемом значении function — это то, что было передано в качестве CAR вычисленного списка, или выражение lambda в случае вызова макроса. Если функция имеет аргумент &rest, он представлен как хвост списка arg-values.

Если указан base, frame-number отсчитывается относительно самого верхнего кадра, чья function равна base.

Если frame-number выходит за пределы диапазона, backtrace-frame возвращает nil.

Функция: mapbacktrace function &optional base

Функция mapbacktrace вызывает function один раз для каждого кадра в обратной трассировке, начиная с первого кадра, функция которого равна base (или с вершины, если base опущен или равен nil).

function вызывается с четырьмя аргументами: evald, func, args и flags.

Если кадр ещё не вычислил свои аргументы или является специальной формой, evald равен nil, а args — список форм.

Если кадр вычислил свои аргументы и уже вызвал свою функцию, evald равен t, а args — список значений. flags — это список свойств текущего кадра в формате plist; в настоящее время единственное поддерживаемое свойство — :debug-on-exit, которое равно t, если установлен флаг debug-on-exit данного кадра стека.