[Openmcl-devel] low level faults

Bill St. Clair wws at clozure.com
Tue Dec 2 08:41:51 PST 2014


The error being signalled is of class ccl::invalid-memory-access, which is
a subclass of cl:storage-condition. This is more serious than an error, and
is not a subclass of cl:error, hence trying to handle a cl:error won't
work. It's usually best NOT to attempt to handle errors of this type, since
they may mean that memory is corrupted. In your case, compiling with
(optimize (speed 3) (safety 0)) means that you promise that you won't
attempt to change the cdr of anything but a cons.

With the optimization, the compiler generates code that doesn't check for
wrong number of arguments or types:

CL-USER> (defun f (x)
           (declare (optimize (safety 0) (speed 3)))
           (rplacd x 1))
F
CL-USER> (disassemble 'f)
L0
         (leaq (@ (:^ L0) (% rip)) (% fn))       ;     [0]
         (pushq (% rbp))                         ;     [7]
         (movq (% rsp) (% rbp))                  ;     [8]
         (pushq (% arg_z))                       ;    [11]
         (movq (% arg_z) (% arg_y))              ;    [12]
         (movl ($ 8) (% arg_z.l))                ;    [15]
         (nop)                                   ;    [20]
         (callq (@ .SPRPLACD))                   ;    [22]
         (leaq (@ (:^ L0) (% rip)) (% fn))       ;    [29]
         (movq (% arg_y) (% arg_z))              ;    [36]
         (leaveq)                                ;    [39]
         (retq)                                  ;    [40]

Without the declaration, the compiled code checks for one arg and that the
argument to rplacd is actually a cons cell:

CL-USER> (defun f2 (x)
           (rplacd x 1))
F2
CL-USER> (disassemble 'f2)
L0
         (leaq (@ (:^ L0) (% rip)) (% fn))       ;     [0]
         (cmpl ($ 8) (% nargs))                  ;     [7]
         (jne L61)                               ;    [10]
         (pushq (% rbp))                         ;    [12]
         (movq (% rsp) (% rbp))                  ;    [13]
         (pushq (% arg_z))                       ;    [16]
         (movq (% arg_z) (% arg_y))              ;    [17]
         (movl ($ 8) (% arg_z.l))                ;    [20]
         (movl (% arg_y.l) (% imm0.l))           ;    [25]
         (andl ($ 15) (% imm0.l))                ;    [27]
         (cmpl ($ 3) (% imm0.l))                 ;    [30]
         (jne L69)                               ;    [33]
         (nop)                                   ;    [35]
         (callq (@ .SPRPLACD))                   ;    [38]
         (leaq (@ (:^ L0) (% rip)) (% fn))       ;    [45]
         (movq (% arg_y) (% arg_z))              ;    [52]
         (leaveq)                                ;    [55]
         (retq)                                  ;    [56]
L61
         (uuo-error-wrong-number-of-args)        ;    [61]
L69
         (uuo-error-reg-not-tag (% arg_y) ($ 3)) ;    [69]

The latter signals a different condition than the former if you pass it 0:

CL-USER> (ignore-errors (f2 0))
NIL
#<TYPE-ERROR #x302004355ADD>
CL-USER> (handler-case (f 0) (storage-condition (c) c))
#<CCL::INVALID-MEMORY-ACCESS #x3020041F871D>

-Bill


On Tue, Dec 2, 2014 at 7:59 AM, Jared C. Davis <jared at cs.utexas.edu> wrote:

> Hi,
>
> Suppose I do something utterly boneheaded like:
>
>     (defun f (x)
>       (declare (optimize (safety 0) (speed 3)))
>       (rplacd x 1))
>
>     (f 0)
>
> This leads to an error like this: (on linux-x8664, at least)
>
>     > Error: Fault during write to memory address #x-3
>     > While executing: F, in process listener(1).
>     > Type :POP to abort, :R for a list of available restarts.
>     > Type :? for other options.
>
> Is there a way to catch and handle this error?  It seems for instance
> that (ignore-errors (f 0)) doesn't work and neither does, e.g.,:
>
>     (handler-case
>       (f 0)
>       (error (condition)
>              (format t "Caught error ~a~%" condition)))
>
> Maybe I just need a handler-case for some condition other than "error"?
>
> I understand that this kind of a fault is more serious than your
> typical error that user-level code might provoke.  I imagine that
> simply masking errors like this might be a terrible idea that could,
> for instance, lead to memory corruption that could cause mysterious
> errors later down the road, or that given other arguments F might
> immediately lead to a segmentation fault or similar.
>
> In my particular case, though, users are interacting with CCL via a
> web interface and can't see the CCL console.  So if an error like this
> occurs, I'd like to (try to) capture it and (try to) show it to the
> user so that they know something has gone horribly wrong.
>
> Thanks!
> Jared
>
> --
> Jared C. Davis <jared at cs.utexas.edu>
> 11410 Windermere Meadows
> Austin, TX 78759
> http://www.cs.utexas.edu/users/jared/
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> https://lists.clozure.com/mailman/listinfo/openmcl-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20141202/40bebfb1/attachment.htm>


More information about the Openmcl-devel mailing list