[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
a bug affecting debugging in PCL
There is a bug in the implementation of *print-circle* that
causes some akcl debugging commands (including :bt and :bl)
to cause the following error when PCL is being used:
Unrecoverable error: value stack overflow.
If you are using PCL, add the following lines to the file
pcl/kcl-patches.lisp, after the (in-package "COMPILER") form:
;When a CLOS object is printed, travel_push_object ends up
;traversing almost the whole class structure, thereby overflowing
;the value-stack.
;from lsp/debug.lsp.
;*print-circle* is badly implemented in kcl.
;it has two separate problems that should be fixed:
; 1. it traverses the printed object putting all objects found
; on the value stack (rather than in a hash table or some
; other structure; this is a problem because the size of the value stack
; is fixed, and a potentially unbounded number of objects
; need to be traversed), and
; 2. it blindly traverses all slots of any
; kind of structure including std-object structures.
; This is safe, but not always necessary, and is very time-consuming
; for CLOS objects (because it will always traverse every class).
;For now, avoid using *print-circle* T when it will cause problems.
(progn
(eval-when (compile eval)
(defmacro si::f (op &rest args)
`(the fixnum (,op ,@ (mapcar #'(lambda (x) `(the fixnum ,x)) args) )))
(defmacro si::fb (op &rest args)
`(,op ,@ (mapcar #'(lambda (x) `(the fixnum ,x)) args) ))
)
(defun si::display-env (n env)
(do ((v (reverse env) (cdr v)))
((or (not (consp v)) (si::fb > (fill-pointer si::*display-string*) n)))
(or (and (consp (car v))
(listp (cdar v)))
(return))
(let ((*print-circle* (can-use-print-circle-p (cadar v))))
(format si::*display-string* "~s=~s~@[,~]" (caar v) (cadar v) (cdr v)))))
(defun si::display-compiled-env ( plength ihs &aux
(base (si::ihs-vs ihs))
(end (min (si::ihs-vs (1+ ihs)) (si::vs-top))))
(format si::*display-string* "")
(do ((i base )
(v (get (si::ihs-fname ihs) 'si::debug) (cdr v)))
((or (si::fb >= i end)(si::fb > (fill-pointer si::*display-string*) plength)))
(let ((*print-circle* (can-use-print-circle-p (si::vs i))))
(format si::*display-string* "~a~@[~d~]=~s~@[,~]"
(or (car v) 'si::loc) (if (not (car v)) (si::f - i base)) (si::vs i)
(si::fb < (setq i (si::f + i 1)) end)))))
(defun can-use-print-circle-p (x)
(typecase x
(vector (or (not (eq 't (array-element-type x)))
(every #'can-use-print-circle-p x)))
(cons (and (can-use-print-circle-p (car x))
(can-use-print-circle-p (cdr x))))
(array (or (not (eq 't (array-element-type x)))
(let* ((rank (array-rank x))
(dimensions (make-list rank)))
(dotimes (i rank)
(setf (nth i dimensions) (array-dimension x i)))
(or (member 0 dimensions)
(do ((cursor (make-list rank :initial-element 0)))
(nil)
(declare (:dynamic-extent cursor))
(unless (can-use-print-circle-p (apply #'aref x cursor))
(return nil))
(when (si::increment-cursor cursor dimensions)
(return t)))))))
(t (or (not (si:structurep x))
(let* ((def (si:structure-def x))
(name (si::s-data-name def))
(len (si::s-data-length def)))
(and (not (eq name 'pcl::std-instance))
(dotimes (i len t)
(unless (can-use-print-circle-p (si:structure-ref x name i))
(return nil)))))))))
)