LINUX.ORG.RU

Не работает степпер в рабочем треде Hunchentoot

 ,


0

1

Доброго времени суток!

Имеется следующий код:

(in-package :cl-user)

'#.(ql:quickload :hunchentoot)

(defvar *single-acceptor* nil)

(declaim (optimize (debug 3) (safety 3) 
           (speed 0) (space 0) (compilation-speed 0)))
(proclaim '(optimize (debug 3) (safety 3) 
           (speed 0) (space 0) (compilation-speed 0)))

(defun inner-fun () (break) "<p>blah-blah-blah</p>")

(defun my-page (&rest ignore)
  (declare (ignore ignore))
  (concatenate 'string "<html><body>" 
    (string-downcase (inner-fun)) 
  "</body></html>"))


(defun restart-server ()
  (setf hunchentoot:*catch-errors-p* nil)
  (when *single-acceptor* 
    (hunchentoot:stop *single-acceptor*))
  (setf *single-acceptor* 
    (make-instance 'hunchentoot:easy-acceptor :port 2800))
  (hunchentoot:start *single-acceptor*)
  (hunchentoot:define-easy-handler 
    (mypage-symbol :uri "/mypage") () (my-page)))

(restart-server)

Я его скомпилировал и загрузил из SLIME. Запускаю my-page, она падает в отладчик. Переключаюсь в режим шагов с помощью буквы «s», могу шагать.

Теперь открываю в браузере http://127.0.0.1:2800/mypage Опять падаю в дебаггер. Нажимаю «s», появляется в минибуфере сообщение «Evaluation aborted on NIL» и выполнение продолжается (страница передаётся в браузер).

Куда копать?

★★★★★

Ответ на: комментарий от deterok

Да чё монк, наверное, это надо дебаггер в зубы, и смотреть, что они недопилили в CMU CL :) Хотя если monk поможет, то я только за :)

den73 ★★★★★
() автор топика

Что-то я не понял. Ты хочешь степпер не в том потоке, в котором работает REPL?

А как это должно быть физически? Единственное, что могу придумать — запускать swank в этом потоке, чтобы к нему можно было соединиться.

Вообще, мне всегда хватало (setf *show-lisp-errors-p* T) (setf *show-lisp-backtraces-p* T)

monk ★★★★★
()
Ответ на: комментарий от den73

Я им багу написал

Это же не бага. Ну или шли разработчикам ядра линукса «багу»:

$ touch a
$ touch b
$ cp -i a b &
$ [1] 17104
 cp: переписать «b»? y
-bash: y: команда не найдена

[1]+  Stopped                 cp -i a b

«Не работает» подтверждение для команды cp.

monk ★★★★★
()
Ответ на: комментарий от monk

В лиспворксе это работает.

Я так понимаю, что степпер - это последовательность вызовов invoke-debugger. Invoke-debugger (из slime) работает в любом треде. Почему степпер не должен работать - я не вижу.

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Invoke-debugger (из slime) работает в любом треде.

Уверен? В смысле, и на кнопки реагирует и позволяет рестарт выбрать?

monk ★★★★★
()
Ответ на: комментарий от monk

Уверен? В смысле, и на кнопки реагирует и позволяет рестарт выбрать?

Канешна! На том стоим!

(sb-thread:make-thread (lambda () (break "wow!")))
; или
(bt:make-thread (lambda () (break "wow!")))

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

На самом-то деле swank плодит множество тредов, твоё (+ 2 2), написанное в REPL, 90%, что будет вычисляться не в главном треде.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Там упоминается три символа,

sb-thread:with-new-session , sb-thread:make-listener-thread, sb-thread:get-foreground.

Похоже, ни один из них в SLIME не упомянут.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Сел разбираться. Текущий код выглядит так:

(in-package :cl-user)

#.(import 'sb-thread::*session*)
#.(import 'sb-thread::*current-thread*)
#.(import 'sb-thread::get-foreground)
#.(import 'sb-thread::release-foreground)
#.(import 'sb-thread::with-new-session)
#.(import 'sb-thread:make-thread)
#.(import 'sb-thread::foreground-thread)
#.(import 'sb-impl::stepping)
#.(import 'sb-thread::thread-stepping)
#.(import 'sb-impl::stepping-enabled-p)
#.(import 'sb-thread:list-all-threads)
#.(import 'sb-thread:thread-name)

; for stepper, must be 
; debug > max(speed,compilation-speed,space)
(declaim (optimize (debug 3) (speed 0) (compilation-speed 0) (space 0)))

(defun f (x)
  "Outer function"
  (+ (g x) (+ x x))
  ;(sleep 1)
  ;(print "f says bye")
  (finish-output))

(defun g (y)
  "Inner function"
  (break)
  (format t "~%My (stepping-enabled-p) is ~A. ~S~%" (stepping-enabled-p) (thread-name *current-thread*))
  (+ y 4)
  )  

(defun f2 ()
  (format t "I wanna to be a master. Type (release-foreground) and give me a thron"
            )
  (get-foreground)
  (progn ; unwind-protect
      (f 5)
    (print "Bye")
    (finish-output)
    (release-foreground)))

(defun tr (s) (sb-thread:make-thread (lambda () (funcall s)) :name "WOW"))


; (trace sb-thread::debugger-wait-until-foreground-thread)

(setf *evaluator-mode* :interpret)

Диалог после компиляции файла примерно такой:

* (tr 'f2)
I wanna to be a master. Type (release-foreground) and give me a thron
#<SB-THREAD:THREAD "WOW" RUNNING {240F08B1}>
* (release-foreground)


Resuming thread #<THREAD "WOW" RUNNING {240F08B1}>

debugger invoked on a SIMPLE-CONDITION in thread
#<THREAD "WOW" RUNNING {240F08B1}>:
  break

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Return from BREAK.
  1: [ABORT   ] abort thread (#<THREAD "WOW" RUNNING {240F08B1}>)

(G 5)
   source: (BREAK)
0] start

My (stepping-enabled-p) is T. "WOW"

"Bye" Resuming thread #<THREAD "main thread" RUNNING {23FF21A1}>
Т.е., я вынес за скобки (вроде бы) и понятие фонового/переднепланового потока. В треде всё равно не работает степпер, даже если тред сделать переднеплановым.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

И так тоже не работает:

(sb-thread:make-thread (lambda () (get-foreground) (step (f2))) :name "WOW")

Надо написать (release-foreground) после запуска, чтобы он отвис. Запускается без шагов, доходит до (break), при попытке перейти в пошаговый режим продолжается без шагов.

Ага! Значит, можно просто пытаться заставить работать степпер в треде, необязательно переходить в пошаговый режим. Это немного облегчает мой труд.

den73 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.