crategus / cl-cffi-gtk

cl-cffi-gtk is a Lisp binding to the GTK+ 3 library.
http://www.crategus.com/books/cl-cffi-gtk
146 stars 33 forks source link

within-main-loop aborts with DIVISION-BY-ZERO in SBCL 1.2.4 on amd64 in SLIME #28

Open plops opened 10 years ago

plops commented 10 years ago

When trying to run this code (which is just one of the demos from the tutorial) from within SLIME in Emacs, the program aborts with a DIVISION-BY-ZERO signal.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload :cl-cffi-gtk))

(defpackage :myclock 
  (:use :gtk :gdk :gobject :glib :pango :cairo :cffi :iterate :cl))

(in-package :myclock)

(defclass clock-face (gtk-drawing-area)
  ((time :initarg :time
     :initform (multiple-value-list (get-decoded-time))
     :accessor clock-face-time))
  (:metaclass gobject-class))

(defmethod initialize-instance :after ((clock clock-face) &key &allow-other-keys)
  (g-timeout-add 1000 (lambda ()
            (setf (clock-face-time clock)
                  (multiple-value-list (get-decoded-time)))
            (gtk-widget-queue-draw clock)
            +g-source-continue+))
  (g-signal-connect clock "draw"
            (lambda (widget cr)
              (let ((cr (pointer cr))
                (window (gtk-widget-window widget)))
            (cairo-set-source-rgb cr 1.0 1.0 1.0)
            (cairo-paint cr)
            (let* ((x (/ (gdk-window-get-width window) 2))
                   (y (/ (gdk-window-get-height window) 2))
                   (radius (- (min x y) 12)))
              (cairo-arc cr x y radius 0 (* 2 pi))
              (cairo-set-source-rgb cr 1 1 1)
              (cairo-fill-preserve cr)
              (cairo-set-source-rgb cr 0 0 0)
              (cairo-stroke cr)
              (let ((angle (* (/ pi 30) (first (clock-face-time clock)))))
                (cairo-save cr)
                (cairo-set-source-rgb cr 1 0 0)
                (cairo-move-to cr x y)
                (cairo-line-to cr
                       (+ x (* radius (sin angle)))
                       (+ y (* radius (- (cos angle)))))
                (cairo-stroke cr)
                (cairo-restore cr)))

            (cairo-destroy cr)
            t))))

(defun run ()
  (progn ;sb-int:with-float-traps-masked (:divide-by-zero)
   (within-main-loop
     (let ((window (make-instance 'gtk-window :title "clock"
                  :default-width 128
                  :default-height 128))
       (clock (make-instance 'clock-face)))
       (g-signal-connect window "destroy"
             (lambda (widget) (leave-gtk-main)))
       (gtk-container-add window clock)
       (gtk-widget-show-all window)))))
#+nil
(run)

This is the error message:

arithmetic error DIVISION-BY-ZERO signalled
   [Condition of type DIVISION-BY-ZERO]

Restarts:
 0: [ABORT] Abort thread (#<THREAD "cl-cffi-gtk main thread" RUNNING {1004817F53}>)

Backtrace:
  0: ("foreign function: #x200DFF7B96")
  1: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
  2: ((FLET #:WITHOUT-INTERRUPTS-BODY-1226 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
  3: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
  4: ((FLET #:WITHOUT-INTERRUPTS-BODY-647 :IN SB-THREAD::CALL-WITH-MUTEX))
  5: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {7FFFE490ED1B}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THR..
  6: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "cl-cffi-gtk main thread" RUNNING {1004817F53}> #S(SB-THREAD:SEMAPHORE :NAME "Thread setup semaphore" :%COUNT 0 :WAITCOUNT 0 :MUTEX #<..
  7: ("foreign function: call_into_lisp")
  8: ("foreign function: new_thread_trampoline")
 --more--

If I run the code from the command line with sbcl --load gtkclock.lisp it works fine. As a temporary fix I wrap within-main-loop with sb-int:with-float-traps-masked (:divide-by-zero)

LaloHao commented 8 years ago

Try wrapping the function

(sb-int:with-float-traps-masked
    (:divide-by-zero)
  (run))

Edit you could try this

(defmacro gtk-run (&rest body)
  `(sb-int:with-float-traps-masked
       (:divide-by-zero)
     ,@body))

And then just (gtk-run (run))

svillemot commented 6 years ago

Duplicate of #6 and #15. Somehow related to SLIME (the problem does not appear outside of SLIME).

hu-moonstone commented 4 years ago

The environment is different, but I am reporting a situation similar to this issue. Similar errors occurred with Debian 10.2, ECL 16.1.3 and SLIME unused. The problem occurs both in REPL and in executing the binary file after compilation. It always occurs when you perform an operation such as moving the mouse over a window.

I tried with float features with-float-traps-masked but could not work around the problem.

Condition of type: DIVISION-BY-ZERO
#<a DIVISION-BY-ZERO>
C-Entropy commented 2 years ago

It turns out to be caused by %gtk-main called in ensure-gtk-main, so maybe wrap it with sb-int:with-float-traps-masked (:divide-by-zero) is a work around