[armedbear-devel] Bug: Attempt to GO to a tag whose extent has ended quits ABCL
![](https://secure.gravatar.com/avatar/eb8f9935cb28a445bec50c7e9e345908.jpg?s=120&d=mm&r=g)
When attempting to GO to a tag whose dynamic extent has ended, ABCL quits and prints the name of the exception used for internally handling GO (org.armedbear.lisp.Go). I see the same behavior in compiled or interpreted code. CL-USER(1): (lisp-implementation-version) "0.16.0" CL-USER(2): (let ((f nil)) (tagbody (setf f (lambda () (go foo))) foo) (funcall f)) org.armedbear.lisp.Go abcl-src-0.16.0 chandler$ -- Brian Mastenbrook brian@mastenbrook.net http://brian.mastenbrook.net/
![](https://secure.gravatar.com/avatar/b053ca7abf2716d9df3ce01278d60947.jpg?s=120&d=mm&r=g)
On 9/17/09 9:54 PM, Brian Mastenbrook wrote:
When attempting to GO to a tag whose dynamic extent has ended, ABCL quits and prints the name of the exception used for internally handling GO (org.armedbear.lisp.Go). I see the same behavior in compiled or interpreted code.
Filed as [bug ticket #63][63]. Thanks for the report. [63]: http://trac.common-lisp.net/armedbear/ticket/63 -- "A screaming comes across the sky. It has happened before, but there is nothing to compare to it now."
![](https://secure.gravatar.com/avatar/b053ca7abf2716d9df3ce01278d60947.jpg?s=120&d=mm&r=g)
On 9/18/09 1:36 PM, Mark Evenson wrote:
Filed as [bug ticket #63][63]. Thanks for the report.
Tentatively fixed in [r12151][1], as it seems as if the code to convert the thrown Go throwable to the corresponding LispError had been inadvertently left out. But something that easy has me suspicious (was this left out for some other reason), so I would appreciate if one of the other developers could review this bug before we close it in Trac. [1]: http://trac.common-lisp.net/armedbear/changeset/12153 -- "A screaming comes across the sky. It has happened before, but there is nothing to compare to it now."
![](https://secure.gravatar.com/avatar/d360ec751eb90bc963c5b03544d88cf5.jpg?s=120&d=mm&r=g)
2009/9/18 Mark Evenson <evenson@panix.com>:
Tentatively fixed in [r12151][1], as it seems as if the code to convert the thrown Go throwable to the corresponding LispError had been inadvertently left out. But something that easy has me suspicious (was this left out for some other reason), so I would appreciate if one of the other developers could review this bug before we close it in Trac.
Does it cause any ansi-test regressions? If not, I see no problems with it.
![](https://secure.gravatar.com/avatar/e30bc676ee7d74ff2b67b431353a8ab8.jpg?s=120&d=mm&r=g)
Mark Evenson writes:
On 9/18/09 1:36 PM, Mark Evenson wrote:
Filed as [bug ticket #63][63]. Thanks for the report.
Tentatively fixed in [r12151][1], as it seems as if the code to convert the thrown Go throwable to the corresponding LispError had been inadvertently left out. But something that easy has me suspicious (was this left out for some other reason), so I would appreciate if one of the other developers could review this bug before we close it in Trac.
I don't know why there's EVAL, and a separate INTERACTIVE-EVAL. Perhaps Peter Graves can comment about this. That schism is somewhat useful in this case because your change makes this fail: (assert (eql :go (prog () (sys::interactive-eval `(funcall ,(lambda () (go :go)))) (return 42) :go (return :go)))) but the same involving the standard EVAL actually works: (assert (eql :go (prog () (eval `(funcall ,(lambda () (go :go)))) (return 42) :go (return :go)))) -T.
![](https://secure.gravatar.com/avatar/b57bb9396f23199f55a5ee36671d2375.jpg?s=120&d=mm&r=g)
On Fri, 18 Sep 2009 at 18:11:58 +0200, Tobias C. Rittweiler wrote:
I don't know why there's EVAL, and a separate INTERACTIVE-EVAL. Perhaps Peter Graves can comment about this.
INTERACTIVE-EVAL is a wrapper of EVAL used in implementing the REPL. It does two things: (1) sets *, **, etc., and (2) is a last-chance catcher of exceptions. Clearly you don't want the overhead of (1) in EVAL. And I don't think you want EVAL to be a last-chance catcher of exceptions, since you do want (EVAL '(+ 'FOO)) to signal an error. Maybe Interpreter.run() should be the last-chance catcher. -Peter
![](https://secure.gravatar.com/avatar/e30bc676ee7d74ff2b67b431353a8ab8.jpg?s=120&d=mm&r=g)
Mark Evenson <evenson@panix.com> writes:
On 9/18/09 1:36 PM, Mark Evenson wrote:
Filed as [bug ticket #63][63]. Thanks for the report.
Tentatively fixed in [r12151][1], as it seems as if the code to convert the thrown Go throwable to the corresponding LispError had been inadvertently left out. But something that easy has me suspicious (was this left out for some other reason), so I would appreciate if one of the other developers could review this bug before we close it in Trac.
This is not enough. You also have to add a catch to LispThread. (threads:make-thread #'(lambda () (let ((f nil)) (tagbody (setf f (lambda () (go foo))) foo) (funcall f))) :name "foof") And the created thread will die miserably in solitude. -T.
![](https://secure.gravatar.com/avatar/b053ca7abf2716d9df3ce01278d60947.jpg?s=120&d=mm&r=g)
On 9/20/09 1:16 PM, Tobias C. Rittweiler wrote:
Mark Evenson<evenson@panix.com> writes:
On 9/18/09 1:36 PM, Mark Evenson wrote:
Filed as [bug ticket #63][63]. Thanks for the report.
This is not enough. You also have to add a catch to LispThread.
(threads:make-thread #'(lambda () (let ((f nil)) (tagbody (setf f (lambda () (go foo))) foo) (funcall f))) :name "foof")
Unfortunately this doesn't seem to be easy to do in clean manner. As far as I got to investigate, there is no single place in which to make the catch, as we seemingly have multiple code paths for executing forms that fail to share common handler code. For your new test case of making the error appear in a MAKE-THREAD, the handler is actually created within the LispThread(Function, LispThread) constructor, which shares no common code with the place I patched the INTERACTIVE-EVAL handler in Lisp.java. And neither of these share code with the top level eval that can be created by invoking Interpreter.eval(String). Out of time for today, but others please chime in to correct/enhance my understanding. -- "A screaming comes across the sky. It has happened before, but there is nothing to compare to it now."
![](https://secure.gravatar.com/avatar/7d3b9ee133249361afc2b73eb4639038.jpg?s=120&d=mm&r=g)
Here was a solution I used. What I did in my local copy of ABCL, was instead of Keeping a dictionary of javaThread->LisptThread, I made LispThread implement UncaughtExcetionHandler interface. public void uncaughtException(Thread arg0, Throwable arg1) { try { error(new LispError(getMessage(arg1))); } catch (Throwable e) { e.printStackTrace(); throw new RuntimeException(arg1); } } And used (LispThread)somejavaThread.getUncaughtExcetionHandler(); to retreive the LispThread This also catches the wild GOs ----- Original Message ----- From: "Mark Evenson" <evenson@panix.com> To: <armedbear-devel@common-lisp.net> Sent: Monday, September 21, 2009 4:58 AM Subject: Re: [armedbear-devel] [FIXED?] Bug: Attempt to GO to a tag whose extent has ended quits ABCL
On 9/20/09 1:16 PM, Tobias C. Rittweiler wrote:
Mark Evenson<evenson@panix.com> writes:
On 9/18/09 1:36 PM, Mark Evenson wrote:
Filed as [bug ticket #63][63]. Thanks for the report.
This is not enough. You also have to add a catch to LispThread.
(threads:make-thread #'(lambda () (let ((f nil)) (tagbody (setf f (lambda () (go foo))) foo) (funcall f))) :name "foof")
Unfortunately this doesn't seem to be easy to do in clean manner.
As far as I got to investigate, there is no single place in which to make the catch, as we seemingly have multiple code paths for executing forms that fail to share common handler code. For your new test case of making the error appear in a MAKE-THREAD, the handler is actually created within the LispThread(Function, LispThread) constructor, which shares no common code with the place I patched the INTERACTIVE-EVAL handler in Lisp.java. And neither of these share code with the top level eval that can be created by invoking Interpreter.eval(String).
Out of time for today, but others please chime in to correct/enhance my understanding.
-- "A screaming comes across the sky. It has happened before, but there is nothing to compare to it now."
_______________________________________________ armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
![](https://secure.gravatar.com/avatar/e30bc676ee7d74ff2b67b431353a8ab8.jpg?s=120&d=mm&r=g)
Brian Mastenbrook writes:
When attempting to GO to a tag whose dynamic extent has ended, ABCL quits and prints the name of the exception used for internally handling GO (org.armedbear.lisp.Go). I see the same behavior in compiled or interpreted code.
CL-USER(1): (lisp-implementation-version) "0.16.0" CL-USER(2): (let ((f nil)) (tagbody (setf f (lambda () (go foo))) foo) (funcall f)) org.armedbear.lisp.Go abcl-src-0.16.0 chandler$
I found an opposited bug; a case where an error about a non-existing tag is signalled even though the tag is active: (assert (eql :go (prog () (funcall (compile nil (lambda () (go :go)))) (return 42) :go (return :go)))) -T.
![](https://secure.gravatar.com/avatar/eb8f9935cb28a445bec50c7e9e345908.jpg?s=120&d=mm&r=g)
On Sep 18, 2009, at 11:05 AM, Tobias C. Rittweiler wrote:
I found an opposited bug; a case where an error about a non-existing tag is signalled even though the tag is active:
(assert (eql :go (prog () (funcall (compile nil (lambda () (go :go)))) (return 42) :go (return :go))))
-T.
For what it's worth, if you enable the interpreter in SBCL, it gives up and punts on this as well. I can't see doing anything sensible with it myself. This is SBCL 1.0.29, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. CL-USER(1): sb-ext:*evaluator-mode* :INTERPRET CL-USER(2): (assert (eql :go (prog () (funcall (compile nil (lambda () (go :go)))) (return 42) :go (return :go)))) debugger invoked on a SB-EVAL::INTERPRETER-ENVIRONMENT-TOO-COMPLEX- ERROR: Lexical environment of #<INTERPRETED-FUNCTION NIL {1002BAEC89}> is too complex to compile. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-EVAL:PREPARE-FOR-COMPILE #<INTERPRETED-FUNCTION NIL {1002BAEC89}>) 0] -- Brian Mastenbrook brian@mastenbrook.net http://brian.mastenbrook.net/
participants (6)
-
Brian Mastenbrook
-
logicmoo@gmail.com
-
Mark Evenson
-
Peter Graves
-
Tobias C. Rittweiler
-
Ville Voutilainen