?

Log in

No account? Create an account

Previous Entry | Next Entry

breakpoint-ы в SBCL

О них в руководстве ничего не сказано, они позаимствованы в SBCL и похоже, что они в какой-то степени работают. Вот такой скрипт я написал:

;; -*- coding: utf-8; -*-
;; По мотивам https://common-lisp.net/project/cmucl/doc/cmu-user/debug-internals.html

#+named-readtables (named-readtables:in-readtable nil)
(in-package :cl-user)

;; такая оптимизация делает код "steppable", т.е. в нём работает пошаговый отладчик SBCL
(declaim
 (optimize (debug 3) (space 2) (compilation-speed 2) (speed 2) (safety 3))) 

(defun Факториал (Н)
  (cond
   ((= 0 Н) 1)
   (t
    (* Н (Факториал (- Н 1))))))

(defun Функция-обработки-точки-прерывания (Кадр Точка-остановки)
  (break "Точка прерывания ~A" (sb-di:breakpoint-info Точка-остановки)))

(defun Поставить-всевозможные-точки-прерывания (Функция)
  (let* ((Счётчик -1)
         (Debug-function (sb-di:fun-debug-fun Функция)))
    (sb-di:do-debug-fun-blocks
     (Бл Debug-function)
     (sb-di:do-debug-block-locations
      (Кл Бл)
      (sb-di:activate-breakpoint
       (sb-di:make-breakpoint #'Функция-обработки-точки-прерывания
                              Кл :info (incf Счётчик)))))))

(Поставить-всевозможные-точки-прерывания #'Факториал)

(Факториал 0)

При компиляции и загрузке файла такого содержания несколько раз вызывается break. Пройдя вниз по стеку, можно найти вхождения для функции "Факториал" и увидеть исходник того места, где мы сейчас находимся. Правда, таких мест довольно немного.

Короче говоря, мы наблюдаем интерфейс, позволяющий тыкать мышью в исходник на SBCL и ставить в это место точку прерывания. В SLIMЕ я не нашёл упоминаний этой возможности для SBCL, но она есть для CMUCL, с которого всё началось, и для SCL, к-рый является форком SBCL, если я ничего не путаю. На него-то я и собираюсь обратить более пристальное внимание.