From: vy
Subject: sldb-eval-in-frame
Date: 
Message-ID: <1179344407.931951.191280@q75g2000hsh.googlegroups.com>
Hi,

I have a very simple question about SLDB and examining frames. When
SLIME raises a debugger window for the execution of

  (let ((foo 1))
    (break)
    (* 2 foo))

I press `e' and type `foo'. But SLDB complains that FOO is unbound.
Where did I make a mistake? Is there any extra step I need to take to
be able to use that feature? Is this something related with the CL
implementation (SBCL 1.0.3) I'm currently using?


Regards.

P.S. I asked this question in SLIME ml, but couldn't find an answer.
Therefore, I decided to try my chance once more in c.l.l.

From: Daniel Jensen
Subject: Re: sldb-eval-in-frame
Date: 
Message-ID: <87sl9vc0od.fsf@orme.bigwalter.net>
vy <·············@gmail.com> writes:

> I have a very simple question about SLDB and examining frames. When
> SLIME raises a debugger window for the execution of
>
>   (let ((foo 1))
>     (break)
>     (* 2 foo))
>
> I press `e' and type `foo'. But SLDB complains that FOO is unbound.
> Where did I make a mistake? Is there any extra step I need to take to
> be able to use that feature? Is this something related with the CL
> implementation (SBCL 1.0.3) I'm currently using?

It is SBCL trying to be smart, and not a problem with SLIME. Since foo
is used as a constant here, it does not have to be available.

I don't know if it's possible to turn off this optimization. I doubt it.
You'll have to enter a more complex expression. And make sure you have
set the debug level. For example:

    (let ((foo 1))
      (break)
      (setq foo (* 2 foo)))

Here foo must be available, and you can evaluate it in the frame.
From: vy
Subject: Re: sldb-eval-in-frame
Date: 
Message-ID: <1179419109.161295.236240@e65g2000hsc.googlegroups.com>
On May 17, 11:30 am, ······@bigwalter.net (Daniel Jensen) wrote:
> It is SBCL trying to be smart, and not a problem with SLIME. Since foo
> is used as a constant here, it does not have to be available.

Ah! That, kind of, explains the problem.

> I don't know if it's possible to turn off this optimization. I doubt it.
> You'll have to enter a more complex expression. And make sure you have
> set the debug level. For example:
>
>     (let ((foo 1))
>       (break)
>       (setq foo (* 2 foo)))
>
> Here foo must be available, and you can evaluate it in the frame.

Neither this solved the problem. (Maybe I again tried with the wrong
optimization flags.) I'll raise this question in SBCL developers ml
and report back the result.


Regards.
From: Pierre R. Mai
Subject: Re: sldb-eval-in-frame
Date: 
Message-ID: <5b36mnF2qsj8kU1@mid.dfncis.de>
On 2007-05-17 10:30:10 +0200, ······@bigwalter.net (Daniel Jensen) said:

> I don't know if it's possible to turn off this optimization. I doubt it.
> You'll have to enter a more complex expression. And make sure you have
> set the debug level. For example:
> 
>     (let ((foo 1))
>       (break)
>       (setq foo (* 2 foo)))
> 
> Here foo must be available, and you can evaluate it in the frame.

To make your aside about the debug level more understandable: In the 
given expression foo must actually not be available at the break 
instruction, since, unless foo is declared special, it suffices to 
rewrite the given expression so that

(progn
  (break)
  (let ((foo 1))
    (setq foo (* 2 foo))))

and in this instance, we can optimize away nearly everything, so that 
we are just left with

(break)

iff multiplication is elidable, as is assignment of a lexical variable 
which is not live after the assignment.

So in order for the foo lexical to be still visible at the break, we 
really want to prevent SBCL's compiler from performing let-moving based 
on liveness analysis, which can be achieved by setting the optimization 
debug quality to 3 in SBCL, see section 4.6 Debugger Policy Control of 
the SBCL manual, esp.:

> 3
> Level 2 plus all uninterned variables. In addition, lifetime analysis 
> is disabled (even when speed is 3), ensuring that all variable values 
> are available at any known location within the scope of the binding. 
> This has a speed penalty in addition to the obvious space penalty.

So, it would be wise to do

(proclaim '(optimize (debug 3)))

before compiling the expression, or to put

(declaim (optimize (debug 3)))

into the file containing the expression, prior to using compile-file on it,

in order to get the best debuggability.

Regs, Pierre.

(who is desperately trying to delay dealing with bookkeeping chores on 
this rainy thursday, and henced decided to lurk on c.l.l again...)
From: Daniel Jensen
Subject: Re: sldb-eval-in-frame
Date: 
Message-ID: <87veepgpoz.fsf@orme.bigwalter.net>
Pierre R. Mai <····@acm.org> writes:

> On 2007-05-17 10:30:10 +0200, ······@bigwalter.net (Daniel Jensen) said:
>
>>     (let ((foo 1))
>>       (break)
>>       (setq foo (* 2 foo)))
>>
>> Here foo must be available, and you can evaluate it in the frame.
>
> To make your aside about the debug level more understandable: In the
> given expression foo must actually not be available at the break
> instruction,

Yes, you're right. It was not my intention to state something
categorically here.

> So in order for the foo lexical to be still visible at the break, we
> really want to prevent SBCL's compiler from performing let-moving
> based on liveness analysis, which can be achieved by setting the
> optimization debug quality to 3 in SBCL, see section 4.6 Debugger
> Policy Control of the SBCL manual, esp.:

Also see section 4.4.1, Variable Value Availability. It mentions the
above, and also tells that "most source-level optimizations are done
under all compilation policies". This should explain why the original
code snippet was optimized even with debug = 3. If someone knows the
details and I'm mistaken, please speak up.