Выражения оценки в кадре дают только UNBOUND-VARIABLE - PullRequest
2 голосов
/ 13 марта 2012

Я использую SLIME для отладки функции Common Lisp. Внутри функции я сделал так, чтобы она искусственно сигнализировала об ошибке (пытаясь «отладить» - возможно, я должен был перейти) следующим образом:

(define-condition unknown-zone (error)
  ((text :initarg :text :reader text)))

(defun parse-mime-date (date)
  (let ((last-space (position #\Space date :from-end t)))
    (let ((date-time (net.telent.date:parse-time (subseq date 0 last-space)))
          (zone (subseq date (1+ last-space))))
      (unless (or (char= (elt zone 0) #\+)
                  (char= (elt zone 0) #\-))
        (error 'unknown-zone :text (format nil "Unknown timezone: ~a" zone)))
      (let ((hours (parse-integer (subseq zone 0 3)))
            (minutes (parse-integer
                      (concatenate 'string
                                   (list (elt zone 0))
                                   (subseq zone 3)))))
        (error 'unknown-zone :text "LOL")
        (let ((adjusted-date-time (- date-time (* 60 (+ minutes (* 60 hours))))))
          (format t "date-time: ~a; zone: ~a~%" date-time zone)
          (format t "adjusted: ~a" (net.telent.date:universal-time-to-http-date adjusted-date-time)))))))

Я пытаюсь обойти то, что, по-видимому, является недостатком net.telent.date:parse-time (кажется, что это мешает обработке часового пояса, хотя я еще не на 100%).

Ошибка "LOL" unknown-zone - это, конечно, искусственная точка останова.

Когда он попадает в эту часть функции, SLDB точно открывается с обратной трассировкой:

Bad type argument:
  NS-MAIL2ZD::UNKNOWN-ZONE
   [Condition of type SIMPLE-TYPE-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 7: #<CLOSURE (LABELS SWANK-BACKEND::RUN :IN SWANK-BACKEND:ADD-FD-HANDLER) {10030AD9FB}>>
 3: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: (MAKE-CONDITION NS-MAIL2ZD::UNKNOWN-ZONE :TEXT "LOL")
  1: (ERROR NS-MAIL2ZD::UNKNOWN-ZONE :TEXT "LOL")
  2: (NS-MAIL2ZD:PARSE-MIME-DATE "Wed, 14 Mar 2012 06:59:36 +1100")
  3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (NS-MAIL2ZD:PARSE-MIME-DATE *LOL*) #<NULL-LEXENV>)
  4: (EVAL (NS-MAIL2ZD:PARSE-MIME-DATE *LOL*))
 --more--

Затем я перехожу к рамке:

Backtrace:
  0: (MAKE-CONDITION NS-MAIL2ZD::UNKNOWN-ZONE :TEXT "LOL")
  1: (ERROR NS-MAIL2ZD::UNKNOWN-ZONE :TEXT "LOL")
      Locals:
        SB-KERNEL::ARGUMENTS = (:TEXT "LOL")
        SB-KERNEL::DATUM = NS-MAIL2ZD::UNKNOWN-ZONE
  2: (NS-MAIL2ZD:PARSE-MIME-DATE "Wed, 14 Mar 2012 06:59:36 +1100")

Теперь я нажимаю e , чтобы вызвать sldb-eval-in-frame и введите last-space, так как это должно быть доступно там, где было сообщено об ошибке.

Кажется, это не так (?) Для работы:

The variable LAST-SPACE is unbound.
   [Condition of type UNBOUND-VARIABLE]

Restarts:
 0: [ABORT] Return to sldb level 1.
 1: [RETRY] Retry SLIME REPL evaluation request.
 2: [*ABORT] Return to SLIME's top level.
 3: [REMOVE-FD-HANDLER] Remove #<SB-IMPL::HANDLER INPUT on descriptor 7: #<CLOSURE (LABELS SWANK-BACKEND::RUN :IN SWANK-BACKEND:ADD-FD-HANDLER) {10030AD9FB}>>
 4: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: ((LAMBDA (#:G1144)) #<unavailable argument>)
 --more--

Есть ли способ сделать то, что я хочу? Я слишком усложняю дела?

Спасибо!


Приложение: Я пытался использовать (break) (это кажется немного более каноничным), но я все еще не могу видеть let связанные переменные с e . <</p>

Ответы [ 3 ]

3 голосов
/ 13 марта 2012

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

Обратите внимание, что имеет смысл определить настройку оптимизации по умолчанию на основе ваших требований.

  • не установлен безопасность очень низкий в глобальном масштабе.Делайте это только в тех разделах кода, где это полезно.

  • не устанавливайте скорость очень высокой в ​​глобальном масштабе.Делайте это только в тех разделах кода, где это полезно.

  • хранить отладочную информацию, используйте настройку 2. В зависимости от реализации высокая настройка отладки может отключить оптимизацию хвостового вызова (TCO)- который может быть нежелателен для выполнения и желателен для отладки.

Я бы предложил различные настройки для:

  • разработка: безопасная + дружественная к отладке
  • развертывание: безопасное
  • оптимизация числового кода локально для скорости

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

  • скорость 1-2.скорость несколько важна
  • безопасность 2-3.безопасность очень важна.все операции проверяются во время выполнения
  • отладка 2-3.отладочная информация сохраняется, и операции должны прерываться отладчиком.
  • пробел 1. Размер кода не важен.
  • скорость компиляции 1. Скорость процесса компиляции равнане так важно.

Диапазон составляет от 0 до 3. Число по умолчанию не превышает 3. 3.

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

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

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

3 голосов
/ 13 марта 2012

Попробуйте использовать полное имя символа (например, package::symbol-name) вместо просто имени символа (например, symbol-name).В текущем случае, возможно, net.telent.date::last-space.

Также убедитесь, что вы скомпилировали с максимальной поддержкой отладки (например, попробуйте поставить (declaim (optimize debug)) перед вашей функцией и перекомпилировать файл - CcCk ).

Проверка того, что код, который вы пытаетесь отлаживать, имеет достаточно информации об отладке: в окне sldb поместите курсор на соответствующую строку в backtrace и нажмите t - это должно расширить кадр и показать значения для всех местных жителей.При повторном нажатии t информация о локальном кадре сворачивается.Если отладочной информации недостаточно, вы не увидите локальные переменные, но некоторые составленные имена (например, SB-DEBUG:ARG-0 в SBCL).Внутри окна sldb, если вы нажмете Enter с курсором на значении, оно развернет это значение в окне инспектора (полезно, если значение представляет собой длинный список, который показан усеченным).

Кроме того, поддержка отладки SLIME зависит от реализации.Приведенный выше совет работает на SBCL под Linux, YMMV под разные реализации.

2 голосов
/ 13 марта 2012

Переменная, кажется, оптимизирована. Из SBCL Manual :

Значение переменной может быть недоступно по следующим причинам:

  1. Возможно, значение качества отладочной оптимизации было опущено. информация, необходимая для определения доступности переменной. Если переменная не является аргументом, ее значение будет доступно только когда отладка не менее
  2. Компилятор сделал анализ времени жизни и определили, что значение больше не нужно, хотя его область не был выход. Анализ времени жизни запрещен при отладке качество оптимизации
  3. Имя переменной не содержит символ (генсим). Чтобы сэкономить место, компилятор выдает только отладку информация о неинтернизированных переменных при отладочной оптимизации качество
  4. Местоположение фрейма неизвестно (см. Раздел 5.3.5 [Неизвестные расположения и прерывания], стр. 31), потому что был введен отладчик из-за прерывания или непредвиденной аппаратной ошибки. Под этим условия значения аргументов будут доступны, но могут быть неверен. Это исключение, упомянутое выше.
  5. Переменная (или код, ссылающийся на него) был оптимизирован из существования. переменные без чтения всегда оптимизированы прочь. Степень, в которой Компилятор удаляет переменные будет зависеть от значения Качество оптимизации скорости компиляции, но большинство исходных текстов оптимизации выполняются в соответствии со всеми политиками компиляции.
  6. Переменная никогда не устанавливается, и ее определение выглядит как (LET ((var1 var2)) ...) В этом случае var1 заменяется на var2.
  7. Переменная никогда не устанавливается и на нее ссылаются ровно один раз. В этом случае ссылка заменяется начальным значением переменной

Вы можете просмотреть все доступные локальные переменные с помощью t .

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

...