gb at clozure.com
Mon Aug 9 10:10:13 PDT 2004
On Sun, 8 Aug 2004, Hamilton Link wrote:
> Yes the backtrace window that shows the stacks may not have a notion of
> history, _but_ the listener that's sitting there in a break loop
> certainly does.
> > I envision an outline interface that would let me scroll through the
> > stack frames, expanding them as needed, similar to the inspector (but
> > different, see below).
> Oh, by the way, I like your vision on this AND a preliminary version of
> this exists so you don't need to start from scratch! The list archive I
> think has an email on how to invoke it when you're in the break loop,
> maybe Gary could reiterate this.
If the frontmost listener window is in a break loop, the
"Backtrace/cmd-shift-B" menu item on the "Lisp" menu is active; choosing
that menu item pops up an outline-based backtrace dialog (which should
be connected to the inspector, to meta-., to all of those nice things ...
I think that the stack-parsing stuff that that backtrace dialog uses
is right (or pretty close to right); I'd want to look carefully at
the code that tries to interpret special-binding information on another
thread's stacks, since that is always a little more complicated than I
think it is.
Exiting a break loop notifies the GUI that any backtrace window associated
with that break loop should be invalidated. "Invalidated" means "closed"
in the current code; it might plausibly mean something else, but whatever
it means, the stack frames that the backtrace dialog had been looking at
aren't necessarily there anymore.
> > In a
> > perfect world I would be able to select a stack frame and invoke a
> > listener that would continue
> > from that point so that I could, say, step through a code sequence
> > repeatedly, starting from the same point each time without actually
> > rerunning the entire program.
> Well, you can kind of do that already, restart from a particular frame
> that is... IF restarts have been declared. In general what it sounds
> like you're suggesting is only possible in languages where you have
> copyable continuations. And unless there's some scheme implementation
> that does this, I don't think there are any such languages. Which would
> be consistent with the world not being perfect.
MCL's backtrace offered the ability to restart/return to (most) arbitary
stack frames. The compiler doesn't really provide quite enough information
about stack and register usage to make this reliable, so there's some
backtrace-related code somewhere that partially disassembles functions
that it finds on the stack in order to try to reconstruct this information.
This is (or was) an amazing hack that worked well enough to impress
people while giving demos of RESTART-FRAME/RETURN-FROM-FRAME; I'm not
sure that I ever used the functionality when not giving a demo, but
that may have been because I knew how fragile the underlying support
This came up on this list several months ago; someone mentioned that
some implementations compile a CATCH around the body of every function
compiled under debugging-oriented optimization settings (and
RESTART/RETURN-FROM-FRAME threw to that CATCH.) A less extreme approach
would be for the compiler to annotate each function with a little more
metainformation than it currently provides (e.g., for it to provide
the information that backtrace tries to recover by partial disassembly.)
Since I knew The Awful Truth about how this was implemented in MCL
(bits and pieces of the code are still in OpenMCL, somewhere or other),
I'll disqualify myself from expressing an opinion about whether RESTART/
RETURN-FROM-FRAME is useful debugging functionality or ... something
> > If I get my wish about branching listeners from arbitrary frames then
> > we could just bring up a new listener as some kind of child of the
> > paused one (it would have to be a child so that it could go away when
> > execution continues in the main window).
> Hmm... I partially withdraw my previous statement about copyable
> continuations. It is possible from the command line to, at a break
> prompt, evaluate whatever you like, so maybe what you want is the break
> loop REP itself. You can process-interrupt a process at any point (or
> at least you could at one time, did native threads break this?) to
> evaluate anything, even to the point of starting a break loop.
PROCESS-INTERRUPT can interrupt a thread at any time (unless that
thread is inside a WITHOUT-INTERRUPTS.) The interrupted thread
receives an asynchronous signal; in general, this can happen on
any instruction boundary.
> I don't know what the evaluation context in a break loop looks like
> exactly. I don't think you can see into the stack without calling out
> values explicitly. I don't think it would do what you are thinking
> you'd like to do, but please describe what you have in mind in more
> depth and maybe Gary will be able to say what is and isn't possible.
When someone talks about "branching listener [thread]s", the first
images that come to mind involve things like Scheme's CALL/CC and
Unix's #_fork, and both of these things are a ways removed from what
a CL thread (however it's scheduled) is.
More information about the Openmcl-devel