7max / log4cl

Common Lisp logging framework, modeled after Log4J
Apache License 2.0
103 stars 32 forks source link

Memory fault with non-logger in explicit logger position #2

Closed 7max closed 12 years ago

7max commented 12 years ago

On Thu, May 10, 2012 at 5:25 PM, Alistair Gee ...... wrote: Hi,

I am using log4cl (latest via quicklisp) and SBCL 1.0.55 on 64-bit Linux.

The following will cause a memory fault:

    (defun foo ()
      (handler-case
          (assert nil)
        (error (e)
          (log:i e))))

    CL-USER> (foo)
    CORRUPTION WARNING in SBCL pid 15228(tid 140698642544384):
    Memory fault at 336 (pc=0x100e41a963, sp=0x7ff6f49bdbd0)
    The integrity of this image is possibly compromised.
    Continuing with fingers crossed.

I am actually trying to print out an error that I've defined as:

    ;;; define my own error type
    (define-condition my-error (error)
      ((text :initarg :text :reader text :type (or null string)))
      (:report (lambda (c s)
                 (declare (type stream s))
                 (format s "my error: ~a" (text c)))))

    ;;; (format) can print out the error without crashing.
    (defun foo2 ()
      (handler-case
          (assert nil nil 'my-error :text "hello")
        (error (e)
          (format t "I can print out the error via (format): ~A" e))))

    ;;; However, (log:i) will crash SBCL when attempting to print out the error.
    (defun foo3 ()
      (handler-case
          (assert nil nil 'my-error :text "hello")
        (error (e)
          (log:i e))))

This is certainly a SBCL bug, but I am not sure where to start looking. Let me know what how I can help you track this down.

7max commented 12 years ago

Problem is that (log:stmt <non-const-value>) treats <non-const-value> as logger, and it uses `(locally (declare (optimize (speed 3) (safety 0))' for the check if logging is enabled on the logger, and since e is not a logger, it gets memory fault error

There are log:expr like alises for other log levels called log:sexp-info, log:sexp-trace etc.. So you probably wanted to use (log:sexp-info e), which would print e=#<value of error> with INFO log level... (I'm open to suggestion as to better naming of these, one idea I have is two letter aliases starting, as in si, sw, st for sexp-info, sexp-warn, sexp-trace... Or maybe pi, pw, pt, with p standing for print)

Thanks for the bug report, since generating the safety 0 thing is done at macro expansion time, it should be easy to fix and have it do (safety 1) for the case of (log:info var).., in which case you would get type-error that "e is not of type logger" instead of memory fault.

I'll make the fix today, but don't know if it will make it into the quicklisp release being built this Sunday

7max commented 12 years ago

This had now been fixed, I hope it makes it into next QuickLisp