throw to invalid tag hoses thread
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
affects sbcl
done
Consider the following (invalid) code, typed at the repl:
(defun call/cc (f) (flet ((k (r) (return-from call/cc r))) (funcall f #'k)))
(call/cc #'call/cc)
(funcall * 3)
I get, using recent sbcl on x86-64, a memory fault at 0 with no
restarts.
There are a variety of related symptoms. Loading
(defun call/cc (f) (flet ((k (r) (return-from call/cc r))) (funcall f #'k)))
(funcall (call/cc #'call/cc) 3)
as source gets me into LDB with multiple corruption warnings; compiling
and loading it gets me into the lisp debugger, but with an infinite
series of memory faults, which also happens with (declaim (optimize safety))
at the top of the file. Compiling and loading
(defun call/cc (f) (flet ((k (r) (return-from call/cc r))) (funcall f #'k)))
(defun kill ()
(let ((cc (call/cc #'call/cc)))
(funcall cc 3)))
gets me into LDB with an "unhandled SIGILL". (With (optimize safety) in
this variant, I seem to get into an infinite loop instead).
I know that all of this is undefined behaviour, but particularly at high
safety it would be nice I think to not crash the whole thread (or lisp
if you are working at an old-school REPL.)
If that's the same family of bugs I discussed with Christophe last week, I believe the issue is that the code we use to mark NLX tags as obsolete isn't in an UWP. The examples above, with their heavy use off NLX, jumps *over* the obsolete-marking code. I thought about moving our guard code to an UWP, but I think it's smarter to handle that explicitly during UNWIND.