made debugger handle errors in printing *DEBUG-CONDITION*
authorWilliam Harold Newman <william.newman@airmail.net>
Sat, 28 Oct 2000 19:04:57 +0000 (19:04 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Sat, 28 Oct 2000 19:04:57 +0000 (19:04 +0000)
BUGS
NEWS
TODO
doc/beyond-ansi.sgml
doc/sbcl.1
src/code/array.lisp
src/code/debug.lisp
src/code/describe.lisp
src/code/late-target-error.lisp
src/runtime/interrupt.c
version.lisp-expr

diff --git a/BUGS b/BUGS
index 7fde253..71f2d77 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -5,8 +5,8 @@ Bugs can be reported on the help mailing list
 or on the development mailing list
   sbcl-devel@lists.sourceforge.net
 
-Please please please include enough information in a bug report
-that someone reading it can reproduce the problem, i.e. don't write
+Please include enough information in a bug report that someone reading
+it can reproduce the problem, i.e. don't write
      Subject: apparent bug in PRINT-OBJECT (or *PRINT-LENGTH*?)
      PRINT-OBJECT doesn't seem to work with *PRINT-LENGTH*. Is this a bug?
 but instead
@@ -70,7 +70,7 @@ TODO file. Eventually more such information may move here.)
   specifically required by the ANSI spec.)
 
 4:
-  It should cause a STYLE-WARNING, not a WARNING, when the system ignores
+  It should cause a note, not a WARNING, when the system ignores
   an FTYPE proclamation for a slot accessor.
 
 5:
@@ -707,9 +707,6 @@ SBCL: (("blah") ("blah2"))
        b: READ should probably return READER-ERROR, not the bare 
           arithmetic error, when input a la "1/0" or "1e1000" causes
           an arithmetic error.
-       c: (BUTLAST NIL) should return NIL. (This appears to be a compiler
-          bug, since the definition of BUTLAST, when interpreted, does
-          give (BUTLAST NIL)=>NIL.)
 
 52:
   It has been reported (e.g. by Peter Van Eynde) that there are 
@@ -741,18 +738,6 @@ SBCL: (("blah") ("blah2"))
 Error in function C::GET-LAMBDA-TO-COMPILE:
    #<Closure Over Function "DEFUN (SETF MACRO-FUNCTION)" {480E21B1}> was defined in a non-null environment.
 
-57:
-  In sbcl-0.6.7, the compiler accepted a bogus declaration
-  (TYPE INDEX LENGTH) in the definition of BUTLAST, and then died
-  with infinite regress of errors when the BUTLAST function was
-  executed with a LIST=NIL which would cause LENGTH to be -1.
-  I fixed the bogus declaration, but I should come back and see
-  whether the system's inability to recover from the bogus declaration
-  (by signalling a TYPE-ERROR and dropping into the debugger) was 
-  a compiler problem which remains to be fixed, or one of the 
-  unrelated infinite-regress-errors problems, many related to 
-  revised signal handling, which were fixed around the same time.
-
 58:
   (SUBTYPEP '(AND ZILCH INTEGER) 'ZILCH)
   => NIL, NIL
diff --git a/NEWS b/NEWS
index 7760233..8bdb4a6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -522,3 +522,13 @@ changes in sbcl-0.6.8 relative to sbcl-0.6.7:
   diff-related operations.
 * fixed the PROG1-vs.-PROGN bug in HANDLER-BIND (reported by 
   ole.rohne@cern.ch on cmucl-help@cons.org 2000-10-25)
+
+changes in sbcl-0.6.9 relative to sbcl-0.6.8:
+
+?? DESCRIBE now works on CONDITION objects.
+?? The debugger now handles errors which arise when trying to print
+  *DEBUG-CONDITION*, so that it's less likely to fall into infinite
+  regress.
+?? signal handling reliability
+?? fixed some bugs mentioned in the man page:
+  ?? DEFUN-vs.-DECLAIM
diff --git a/TODO b/TODO
index e3a1964..c9dc3fe 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-    Accumulation of half-understood design decisions eventually
+i    Accumulation of half-understood design decisions eventually
     chokes a program as a water weed chokes a canal. By refactoring
     you can ensure that your full understanding of how the program
     should be designed is always reflected in the program. As a
index 3c1a434..eb789f0 100644 (file)
@@ -130,18 +130,13 @@ calling external C code, described
 specified by &ANSI;. Weak pointers allow references to objects to be
 maintained without keeping them from being GCed. And "finalization"
 hooks are available to cause code to be executed when an object is
-GCed.</para>
+GCed.</para> <!-- FIXME: Actually documenting these would be good.:-| -->
 
 <para>&SBCL; does not currently provide Gray streams, but may do so in
 the near future. (It has unmaintained code inherited from &CMUCL; to
 do so.) <!-- FIXME: Add citation to Gray streams.-->
 </para>
 
-<para>&SBCL; does not currently support multithreading (traditionally
-called <wordasword>multiprocessing</> in &Lisp;) but contains unmaintained
-code from &CMUCL; to do so. A sufficiently motivated maintainer
-could probably make it work.</para>
-
 </sect2>
 
 <sect2><title>Support for Unix</>
index 4bf0893..6ec7939 100644 (file)
@@ -227,12 +227,14 @@ doc strings and online help built into the SBCL executable
 .SH SYSTEM REQUIREMENTS
 
 Unlike its distinguished ancestor CMU CL, SBCL is currently only
-supported on X86. Linux and FreeBSD are currently available. It would
-probably be straightforward to port the CMU CL support for Alpha or
-SPARC as well, or to OpenBSD or NetBSD, but at the time of this
-writing no such efforts are underway.
-
-As of version 0.6.3, SBCL requires on the order of 16Mb to run. In
+supported on X86. Linux, FreeBSD, and OpenBSD ports are currently
+available. It would probably be straightforward to port the CMU CL
+support for SPARC or Alpha, or to port to NetBSD. Some work on a
+port to the Alpha has been reported on the mailing lists; check
+the archives (available from the home page at
+<http://sbcl.sourceforge.net/>) for information.
+
+As of version 0.6.8, SBCL requires on the order of 16Mb to run. In
 some future version, this number could shrink significantly, since
 large parts of the system are far from execution bottlenecks and could
 reasonably be stored in compact byte compiled form. (CMU CL does this
@@ -283,9 +285,9 @@ The system doesn't deal well with stack overflow.
 .TP 3
 \--
 The SBCL system overcommits memory at startup. On typical Unix-alikes
-like Linux and *BSD, this can cause other processes to be killed
-randomly (!) if the SBCL system turns out to use more virtual memory
-than the system has available for it.
+like Linux and *BSD, this means that if the SBCL system turns out to
+use more virtual memory than the system has available for it, other
+processes to be killed randomly (!)
 .PP
 
 The facility for dumping a running Lisp image to disk gets confused
@@ -295,9 +297,9 @@ high-water mark). Moreover, when the file is loaded, it confuses the
 GC, so that thereafter memory usage can never be reduced below that
 level.
 
-By default, the compiler is overaggressive about static typing,
-assuming that a function's return type never changes. Thus compiling
-and loading a file containing
+The compiler is overaggressive about static typing, assuming that a
+function's return type never changes. Thus compiling and loading a
+file containing
 (DEFUN FOO (X) NIL)
 (DEFUN BAR (X) (IF (FOO X) 1 2))
 (DEFUN FOO (X) (PLUSP X))
@@ -317,9 +319,6 @@ never compiled code to check the declaration.
 
 The TRACE facility can't be used on some kinds of functions.
 
-The profiler is flaky, e.g. sometimes it fails by throwing a
-signal instead of giving you a result.
-
 SYMBOL-FUNCTION is much slower than you'd expect, being implemented
 not as a slot access but as a search through the compiler/kernel
 "globaldb" database.
@@ -359,8 +358,9 @@ of the implementation of compound types like (ARRAY * 1).)
 
 .SH SUPPORT
 
-Please send bug reports or other information to
-<william.newman@airmail.net>.
+Various information about SBCL is available at
+<http://sbcl.sourceforge.net/>. The mailing lists there are the
+recommended place to look for support.
 
 .SH DISTRIBUTION
 
index 9bf63aa..4f03dfc 100644 (file)
           (setf (%array-fill-pointer array) (1+ fill-pointer))
           fill-pointer))))
 
-(defun vector-push-extend (new-el array &optional
-                                 (extension (if (zerop (length array))
-                                                1
-                                                (length array))))
+(defun vector-push-extend (new-element
+                          vector
+                          &optional
+                          (extension (1+ (length vector))))
   #!+sb-doc
   "Like Vector-Push except that if the fill pointer gets too large, the
-   Array is extended rather than Nil being returned."
-  (declare (vector array) (fixnum extension))
-  (let ((fill-pointer (fill-pointer array)))
+   Vector is extended rather than Nil being returned."
+  (declare (vector vector) (fixnum extension))
+  (let ((fill-pointer (fill-pointer vector)))
     (declare (fixnum fill-pointer))
-    (when (= fill-pointer (%array-available-elements array))
-      (adjust-array array (+ fill-pointer extension)))
-    (setf (aref array fill-pointer) new-el)
-    (setf (%array-fill-pointer array) (1+ fill-pointer))
+    (when (= fill-pointer (%array-available-elements vector))
+      (adjust-array vector (+ fill-pointer extension)))
+    (setf (aref vector fill-pointer) new-element)
+    (setf (%array-fill-pointer vector) (1+ fill-pointer))
     fill-pointer))
 
 (defun vector-pop (array)
index 79f9504..0c6b537 100644 (file)
@@ -579,6 +579,18 @@ Function and macro commands:
 (defvar *debug-restarts*)
 (defvar *debug-condition*)
 
+;;; Print *DEBUG-CONDITION*, taking care to avoid recursive invocation
+;;; of the debugger in case of a problem (e.g. a bug in the PRINT-OBJECT
+;;; method for *DEBUG-CONDITION*).
+(defun princ-debug-condition-carefully (stream)
+  (handler-case (princ *debug-condition* stream)
+    (error (condition)
+          (format stream
+                  "  (caught ~S when trying to print ~S)"
+                  (type-of condition)
+                  '*debug-condition*)))
+  *debug-condition*)
+
 (defun invoke-debugger (condition)
   #!+sb-doc
   "Enter the debugger."
@@ -587,29 +599,31 @@ Function and macro commands:
       (let ((*debugger-hook* nil))
        (funcall hook condition hook))))
   (sb!unix:unix-sigsetmask 0)
-  (let ((original-package *package*)) ; protect it from WITH-STANDARD-IO-SYNTAX
+  (let ((original-package *package*)) ; protected from WITH-STANDARD-IO-SYNTAX
     (with-standard-io-syntax
      (let* ((*debug-condition* condition)
            (*debug-restarts* (compute-restarts condition))
            ;; FIXME: The next two bindings seem flaky, violating the
-           ;; principle of least surprise. But in order to fix them, we'd
-           ;; need to go through all the i/o statements in the debugger,
-           ;; since a lot of them do their thing on *STANDARD-INPUT* and
-           ;; *STANDARD-OUTPUT* instead of *DEBUG-IO*.
+           ;; principle of least surprise. But in order to fix them,
+           ;; we'd need to go through all the i/o statements in the
+           ;; debugger, since a lot of them do their thing on
+           ;; *STANDARD-INPUT* and *STANDARD-OUTPUT* instead of
+           ;; *DEBUG-IO*.
            (*standard-input* *debug-io*) ; in case of setq
            (*standard-output* *debug-io*) ; ''  ''  ''  ''
-           ;; We also want to set the i/o subsystem into a known, useful 
-           ;; state, regardless of where in the debugger was invoked in the 
-           ;; program. WITH-STANDARD-IO-SYNTAX does some of that, but
-           ;;   1. It doesn't affect our internal special variables like
-           ;;      *CURRENT-LEVEL*.
+           ;; We want the i/o subsystem to be in a known, useful
+           ;; state, regardless of where the debugger was invoked in
+           ;; the program. WITH-STANDARD-IO-SYNTAX does some of that,
+           ;; but
+           ;;   1. It doesn't affect our internal special variables 
+           ;;      like *CURRENT-LEVEL*.
            ;;   2. It isn't customizable.
-           ;;   3. It doesn't set *PRINT-READABLY* or *PRINT-PRETTY* to the
-           ;;      same value as the toplevel default.
+           ;;   3. It doesn't set *PRINT-READABLY* or *PRINT-PRETTY* 
+           ;;      to the same value as the toplevel default.
            ;;   4. It sets *PACKAGE* to COMMON-LISP-USER, which is not
            ;;      helpful behavior for a debugger.
-           ;; We try to remedy all these problems with explicit rebindings
-           ;; here.
+           ;; We try to remedy all these problems with explicit 
+           ;; rebindings here.
            (sb!kernel:*current-level* 0)
            (*print-length* *debug-print-length*)
            (*print-level* *debug-print-level*)
@@ -617,11 +631,14 @@ Function and macro commands:
            (*print-readably* nil)
            (*print-pretty* t)
            (*package* original-package))
+       #!+sb-show (sb!conditions::show-condition *debug-condition*
+                                                *error-output*)
        (format *error-output*
-              "~2&debugger invoked on ~S of type ~S:~%  ~A~%"
+              "~2&debugger invoked on ~S of type ~S:~%  "
               '*debug-condition*
-              (type-of *debug-condition*)
-              *debug-condition*)
+              (type-of *debug-condition*))
+       (princ-debug-condition-carefully *error-output*)
+       (terpri *error-output*)
        (let (;; FIXME: like the bindings of *STANDARD-INPUT* and
             ;; *STANDARD-OUTPUT* above..
             (*error-output* *debug-io*))
index d53dcc6..56f3349 100644 (file)
@@ -84,6 +84,9 @@
          (format s "~:_...")
          (return))
        (format s "~:_(~S ~S)" k v)))))
+
+(defmethod describe-object ((condition condition) s)
+  (sb-conditions::describe-condition condition s))
 \f
 ;;;; DESCRIBE-OBJECT methods for symbols and functions, including all
 ;;;; sorts of messy stuff about documentation, type information,
index 91ecea1..795a5a8 100644 (file)
 
 (def!struct (condition-class (:include slot-class)
                             (:constructor bare-make-condition-class))
-  ;; List of CONDITION-SLOT structures for the direct slots of this class.
+  ;; list of CONDITION-SLOT structures for the direct slots of this
+  ;; class
   (slots nil :type list)
-  ;; List of CONDITION-SLOT structures for all of the effective class slots of
-  ;; this class.
+  ;; list of CONDITION-SLOT structures for all of the effective class
+  ;; slots of this class
   (class-slots nil :type list)
-  ;; Report function or NIL.
+  ;; report function or NIL
   (report nil :type (or function null))
-  ;; List of alternating initargs and initforms.
+  ;; list of alternating initargs and initforms
   (default-initargs () :type list)
-  ;; CPL as a list of class objects, with all non-condition classes removed.
+  ;; class precedence list as a list of class objects, with all
+  ;; non-condition classes removed
   (cpl () :type list)
-  ;; A list of all the effective instance allocation slots of this class that
-  ;; have a non-constant initform or default-initarg. Values for these slots
-  ;; must be computed in the dynamic environment of MAKE-CONDITION.
+  ;; a list of all the effective instance allocation slots of this
+  ;; class that have a non-constant initform or default-initarg.
+  ;; Values for these slots must be computed in the dynamic
+  ;; environment of MAKE-CONDITION.
   (hairy-slots nil :type list))
 
 (defun make-condition-class (&rest rest)
            (:copier nil))
 
   (function-name nil)
-  ;; Actual initargs supplied to MAKE-CONDITION.
+  ;; actual initargs supplied to MAKE-CONDITION
   (actual-initargs (required-argument) :type list)
-  ;; Plist mapping slot names to any values that were assigned or defaulted
-  ;; after creation.
+  ;; plist mapping slot names to any values that were assigned or
+  ;; defaulted after creation
   (assigned-slots () :type list))
 
 (defstruct condition-slot
   (name (required-argument) :type symbol)
-  ;; List of all applicable initargs.
+  ;; list of all applicable initargs
   (initargs (required-argument) :type list)
-  ;; Names of reader and writer functions.
+  ;; names of reader and writer functions
   (readers (required-argument) :type list)
   (writers (required-argument) :type list)
-  ;; True if :INITFORM was specified.
+  ;; true if :INITFORM was specified
   (initform-p (required-argument) :type (member t nil))
-  ;; If a function, call it with no args. Otherwise, the actual value.
+  ;; If this is a function, call it with no args. Otherwise, it's the
+  ;; actual value.
   (initform (required-argument) :type t)
-  ;; Allocation of this slot. Nil only until defaulted.
+  ;; allocation of this slot, or NIL until defaulted
   (allocation nil :type (member :instance :class nil))
-  ;; If :class allocation, a cons whose car holds the value.
+  ;; If ALLOCATION is :CLASS, this is a cons whose car holds the value.
   (cell nil :type (or cons null)))
 
 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
                   (not (typep superclass 'condition-class)))
                 superset))))
 
-;;; KLUDGE: It's not clear to me why CONDITION-CLASS has itself listed in its
-;;; CPL, while other classes derived from CONDITION-CLASS don't have themselves
-;;; listed in their CPLs. This behavior is inherited from CMU CL, and didn't
-;;; seem to be explained there, and I haven't figured out whether it's right.
-;;; -- WHN 19990612
+;;; KLUDGE: It's not clear to me why CONDITION-CLASS has itself listed
+;;; in its CPL, while other classes derived from CONDITION-CLASS don't
+;;; have themselves listed in their CPLs. This behavior is inherited
+;;; from CMU CL, and didn't seem to be explained there, and I haven't
+;;; figured out whether it's right. -- WHN 19990612
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (let ((condition-class (locally
                           ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for
 ) ; EVAL-WHEN
 
 ;;; FIXME: ANSI's definition of DEFINE-CONDITION says
-;;;   Condition reporting is mediated through the print-object method for
-;;;   the condition type in question, with *print-escape* always being nil.
-;;;   Specifying (:report report-name) in the definition of a condition
-;;;   type C is equivalent to:
+;;;   Condition reporting is mediated through the PRINT-OBJECT method
+;;;   for the condition type in question, with *PRINT-ESCAPE* always
+;;;   being nil. Specifying (:REPORT REPORT-NAME) in the definition of
+;;;   a condition type C is equivalent to:
 ;;;     (defmethod print-object ((x c) stream)
 ;;;       (if *print-escape* (call-next-method) (report-name x stream)))
 ;;; The current code doesn't seem to quite match that.
                            ,report
                            (list ,@default-initargs))))))
 \f
+;;;; DESCRIBE on CONDITIONs
+
+;;; a function to be used as the guts of DESCRIBE-OBJECT (CONDITION T)
+;;; eventually (once we get CLOS up and running so that we can define
+;;; methods)
+(defun describe-condition (condition stream)
+  (format stream
+         "~@<~S ~_is a ~S. ~_Its slot values are ~_~S.~:>"
+         condition
+         (type-of condition)
+         (concatenate 'list
+                      (condition-actual-initargs condition)
+                      (condition-assigned-slots condition))))
+\f
 ;;;; various CONDITIONs specified by ANSI
 
-(define-condition serious-condition (condition)())
+(define-condition serious-condition (condition) ())
 
 (define-condition error (serious-condition) ())
 
index bbb00a6..616bc78 100644 (file)
@@ -76,11 +76,12 @@ os_context_t *lisp_interrupt_contexts[MAX_INTERRUPTS];
  * However, some signals need special handling, e.g. the SIGSEGV (for
  * Linux) or SIGBUS (for FreeBSD) used by the garbage collector to
  * detect violations of write protection, because some cases of such
- * signals are handled at C level and never passed on to Lisp. For
- * such signals, we still store any Lisp-level handler in
- * interrupt_handlers[..], but for the outermost handle we use the
- * value from interrupt_low_level_handlers[..], instead of the
- * ordinary interrupt_handle_now(..) or interrupt_handle_later(..).
+ * signals (e.g. GC-related violations of write protection) are
+ * handled at C level and never passed on to Lisp. For such signals,
+ * we still store any Lisp-level handler in interrupt_handlers[..],
+ * but for the outermost handle we use the value from
+ * interrupt_low_level_handlers[..], instead of the ordinary
+ * interrupt_handle_now(..) or interrupt_handle_later(..).
  *
  * -- WHN 20000728 */
 void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*) = {0};
@@ -113,7 +114,7 @@ fake_foreign_function_call(os_context_t *context)
        (lispobj *)(*os_context_register_addr(context, reg_ALLOC));
 #ifdef alpha
     if ((long)dynamic_space_free_pointer & 1) {
-      lose("dead in fake_foreign_function_call, context = %x", context);
+       lose("dead in fake_foreign_function_call, context = %x", context);
     }
 #endif
 #endif
@@ -148,12 +149,13 @@ fake_foreign_function_call(os_context_t *context)
             oldcont = (lispobj)(*os_context_register_addr(context, reg_OCFP));
         }
     }
-    /* ### We can't tell if we are still in the caller if it had to
-     * reg_ALLOCate the stack frame due to stack arguments. */
+    /* ### We can't tell whether we are still in the caller if it had
+     * to reg_ALLOCate the stack frame due to stack arguments. */
     /* ### Can anything strange happen during return? */
-    else
+    else {
         /* normal case */
         oldcont = (lispobj)(*os_context_register_addr(context, reg_CFP));
+    }
 
     current_control_stack_pointer = current_control_frame_pointer + 8;
 
index 82119ac..1b37ed4 100644 (file)
@@ -15,4 +15,4 @@
 ;;; versions, and a string a la "0.6.5.12" is used for versions which
 ;;; aren't released but correspond only to CVS tags or snapshots.
 
-"0.6.8"
+"0.6.8.1"