unbound slot in division-by-zero and other FP exception conditions

Bug #396974 reported by Nikodemus Siivola
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Confirmed
Low
Unassigned

Bug Description

Reported by Gabriel Dos Reis on sbcl-devel:

The form exposes a bug in the SBCL DIVISION-BY-ZERO class.

;; --- cut here
(defun invert-x (x) (/ 1 x))

(defun handle-div-by-zero (c)
 (let ((op (arithmetic-error-operation c))
       (args (arithmetic-error-operands c)))
   (format *error-output* "op = ~A, args = ~A ~%" op args)
   (throw 'result "failed")))

(defun invert (x)
 (handler-bind ((division-by-zero #'handle-div-by-zero))
               (catch 'result (invert-x x))))

(invert 0) ;; OK -- returns "failed"
(invert 0.0) ;; KO -- drops into debugger

;; -- cut here

On gets dropped into the debugger:

debugger invoked on a SIMPLE-ERROR: unbound condition slot: SB-KERNEL::OPERANDS

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

restarts (invokable by number or by possibly-abbreviated name):
 0: [ABORT] Exit debugger, returning to top level.

(SB-KERNEL::FIND-SLOT-DEFAULT
 #<SB-KERNEL::CONDITION-CLASSOID DIVISION-BY-ZERO>
 #S(SB-KERNEL::CONDITION-SLOT
   :NAME SB-KERNEL::OPERANDS
   :INITARGS (:OPERANDS)
   :READERS (ARITHMETIC-ERROR-OPERANDS)
   :WRITERS NIL
   :INITFORM-P NIL
   :INITFORM NIL
   :ALLOCATION :INSTANCE
   :CELL NIL
   :DOCUMENTATION NIL))
0]

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

The bug resides in src/code/float-traps.lisp:

(defun sigfpe-handler (signal info context)
  (declare (ignore signal context))
  (declare (type system-area-pointer info))
  (let ((code (sb!unix::siginfo-code info)))
    (with-interrupts
        (error (or (cdr (assoc code *sigfpe-code-error-alist*))
                   'floating-point-exception)))))

We signal the error without providing either :operation or :operands.

Since all conditions signalled are subclasses or ARITHMETIC-ERROR, that's a bit suboptimal.

Getting access to operation for DIVISION-BY-ZERO is a no-brainer (we can always call it /), for the others it requires parsing the offending instruction -- ditto for operands.

Perhaps defaulting both to NIL is an acceptable least-evil for now?

Changed in sbcl:
status: New → Confirmed
importance: Undecided → Low
Revision history for this message
Leslie P. Polzer (polzer-gnu) wrote :

Alternative:

* ensure that we don't get to handle SIGFPE at all for conditions where operands are needed (at least warn and set the operands to NIL).

* check for division by zero in function / (numbers.lisp), but only if we are in that particular float mode that actually throws an exception in this case.

tags: added: floating-point
removed: fp
Revision history for this message
3b (00003b) wrote :

Also applies to FLOATING-POINT-OVERFLOW conditions, for example from (expt 2.0 1000)

summary: - unbound slot in division-by-zero
+ unbound slot in division-by-zero and other FP exception conditions
Revision history for this message
Stas Boukarev (stassats) wrote :

This is fixed on x86-64 in 8c5db49fc5d0f110d6ac95931317bde4114a7ba1, but the other backends are still affected.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.