[Openmcl-devel] debugging debugging
Arthur W Cater
arthur.cater at ucd.ie
Fri May 8 07:21:19 PDT 2009
Thank you Gary.
I've now put into my ccl-init.lisp the line
(defun cl-user::yield () (process-interrupt ccl::*initial-process* #'break))
which will give me an easily remembered workaround.
As I now understand it, perhaps wrongly, the Listener does run a REPL but not in the appropriate
thread. The break loop in *initial-process* responds to :Y by executing code.
Idea: could the Listener thread not respond to :Y by causing that code to be executed in the
initial process? Perhaps only when it is not itself in a break loop? (If that's daft, feel free to say so!)
Arthur
----- Original Message -----
From: Gary Byers <gb at clozure.com>
Date: Friday, May 8, 2009 12:26 pm
Subject: Re: [Openmcl-devel] debugging debugging
To: Arthur W Cater <arthur.cater at ucd.ie>
Cc: openmcl-devel Devel <openmcl-devel at clozure.com>
>
>
> On Fri, 8 May 2009, Arthur W Cater wrote:
>
> > As I mentioned in March, I have a similar problem with errors
> occurring on other threads,
> > in my case often threads other than the Event�thread.
> > I'm told to type (:Y 8) � eg � but neither the Listener nor
> the AltConsole does anything
> > when I do so. A simple example of this is with
> >
> > (process-run-function "Breaker" #'(lambda nil (break "Talk to me")))
> >
> > The Event thread still runs, but there is no way afaik of
> getting any
> > debugging info, not even a simple backtrace.
> >
> > Arthur
> >
>
> Yuck. Let me see if I can explain what's going on here
> (though I agree that
> what's going on and what should/could be going on are different
> things.)
> When the lisp starts up, it initializes (global) values of the
> standard input
> and output stream variables. When run in a TTY environment
> or under Emacs,
> these streams are (usefully) connected to the process-wide
> standard input
> and output devices (pipes or sockets or terminal-like
> devices). When a GUI
> application is launched on OSX, the devices to which these
> streams are connected
> aren't appropriate for interactive I/O; when the CCL IDE starts
> up, it tries
> to reconnect these streams to devices that talk to the
> AltConsole application
> (which at least provides a primitive way of doing interactive I/O.)
>
> When the (non-GUI) CCL starts up, a listener thread is created
> that uses
> these standard streams (and can therefore talk to a Terminal
> window, Emacs, etc.)
> The listener thread is marked as being the "owner" of the global
> standard input
> stream (since it's expected to make heavy use of that stream, to
> run the REPL,
> etc.) If some background thread needs to do input from
> that stream, it announces
> that fact and advises us to type (:y <n>); in the listener,
> we have to ensure
> that we're talking to the REPL (either at top level or in a
> break loop) and type
> that command in order to (temporarily) transfer the exclusive
> right to use that
> global input stream to the background thread.
>
> If the listener thread isn't in the REPL, we generally have to
> wait until it
> is or interrupt it to get it to that point before typing (:Y
> <n>) will have
> the desired effect.
>
> When the IDE starts up, the initial thread is marked as the
> owner of the global
> input stream (connected to AltConsole). When listener
> windows are created in
> the IDE, the listener threads that are created at the same time
> arrange to use
> interactive streams connected to that listener window (and its
> buffer.) If
> a background thread is created, then by default it will try to
> use the global
> (AltConsole-based) interactive streams. (See below.)
>
> If that background thread needs to use the global input stream (owned
> by the initial/event thread), it'll print a message to that
> effect on
> its standard error or output stream (I forget which, but they'd both
> be associated with AltConsole) and wait for the input stream's owner
> to transfer ownership (via a :y command in a REPL). Of course,
> the input stream's owner is busy processing events isn't really
> runninga REPL, so (as you noted) nothing really happens.
>
> If we were to keep this paradigm (background threads try to do
> emergencyI/O using a shared input stream), then we'd presumably
> want to have some
> other means of doing the equivalent of :Y (a menu command or
> something)that wouldn're require the event thread to be at a
> REPL prompt. If you
> want to see what's going on here or need to handle this
> situation in an
> emergency in the short term, you can do:
>
> - in an IDE listener, do:
>
> ? (process-run-function "background" #'break)
>
> This should cause output to the AltConsole window, announcing
> that the background
> thread wants to enter a break loop and needs someone to type a
> :Y command to let
> it use the global input stream. (Of course, it's not the
> act of typing that
> command that transfers ownership, it's the act of a REPL running
> in the owning
> thread reading and processing that command that does the
> transfer.) The owning
> thread, of course, is busy processing events, so let's change that.
>
> - in the IDE listener, do:
>
> ? (process-interrupt ccl::*initial-process* #'break)
>
> There are several ways to refer to the initial process; sadly, I
> don't know
> of a way that involves exported names.
>
> Event processing should stop, and the initial process should
> have entered a
> break loop in the AltConsole window. In that break loop
> typing the appropriate
> :Y command will do the "ownership transfer" and let the
> background thread use
> the input stream for its break loop; exiting the break loop will
> restore control
> to the event thread (which will be in the break loop we forced
> it into from the
> IDE), and exiting from that break loop will allow the event
> thread to get back
> to processing events.
>
> That's all pretty horrible; it could be made slightly less
> horrible if
> there were some GUI object (a menu item or button or something
> somewhere) that avoided the need to enter a break loop to do the
> ownership transfer of the input stream, but ... well, there's no
> reason for a background thread to have to use the global
> AltConsole-based stream for incidental or other I/O: it could
> create a
> listener window ("on demand") if it needed to do I/O, or try to share
> an existing listener window, or (maybe) create its own AltConsole
> window, or any number or other things. (It's very hard to
> get the
> event thread to do event-driven I/O to and from a GUI window,
> but shouldn't
> be any harder for a random thread to do that than it is for a
> listener.)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20090508/56759ce3/attachment.htm>
More information about the Openmcl-devel
mailing list