Debugger Through slow

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Debugger Through slow

Christoph Thiede

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


Best,

Christoph



Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

marcel.taeumel
Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.

Hmmm... sounds reasonable. Is it difficult to figure this out in the debugger via selected PC?

Best,
Marcel

Am 11.09.2019 13:55:20 schrieb Thiede, Christoph <[hidden email]>:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


Best,

Christoph



Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

Christoph Thiede

Hi Marcel,


wow, this mail was *quite* old. Back in these days, I did not spend any thought about any of the refinements of context - today, I think this was a useless request.

Consider this simple example:
foo := { [self inform: #foo] }.
foo first value "Step through value"
Stepping over instead of through the latest message would have a different effect, even if the statement does not include a block.
Spoken generally, Through should not only "step into a block", but rather "step until the activated context's home equals the currently displayed context home" (just as #stepToHome: describes). Or would you have a different expectation?
Without exploring all pointers of thisContext (😱), I see no longer any feasible option in order to make sure that Through will impossibly reach a nested closure context. Maybe, we could scan thisContext method for any closures, but I have the impression that such kind of edge case optimization would rather lead us to a new source of errors ...
Actually, today I find it much more important to make sure that you can reliably use <cmd>dot to abort the stepping (and ideally, after that restart the context), without destroying your image. Investigating further details about Active Process, #runUntilErrorOrReturnFrom: and, most urgently, recursive error detection in debugger seem appropriate ways to achieve this.

Sorry for the ill-conceived question! :-)

Best,
Christoph

Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Montag, 6. Januar 2020 16:31:24
An: JOHN SARKELA via Squeak-dev
Betreff: Re: [squeak-dev] Debugger Through slow
 
Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.

Hmmm... sounds reasonable. Is it difficult to figure this out in the debugger via selected PC?

Best,
Marcel

Am 11.09.2019 13:55:20 schrieb Thiede, Christoph <[hidden email]>:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


Best,

Christoph



Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

Eliot Miranda-2
In reply to this post by Christoph Thiede
Hi Christoph,

On Wed, Sep 11, 2019 at 4:55 AM Thiede, Christoph <[hidden email]> wrote:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


The way we did it in VisualWorks is to create subclasses of the various BlockClosure classes (in our case of BlockClosure and FullBlockClosure) that override the value[:value*] messages to call back into the debugger, and use adoptInstance: to convert the blocks created in the current activation into these "breaking" blocks.  

The first problem is identifying the set of blocks that need to be morphed into "through" breaking blocks (TBBs for the purposes of this email).
One way would be to simply use [Full]BlockClosure>>allInstances, selecting those whose home is the home context, but that could suck in large images.
Another way would be to somehow intercept block creation while stepping.sending and, say, maintain a dictionary in the debugger from home context to blocks whose home is that context.
IIRC, the VW implementation scanned the outgoing arguments at point of send (from a "through"), looking for blocks.  This is simple but misses cases where blocks are stored in variables, etc.

The second problem is when to do the morphing.  It should be done during the "through" processing, and undone on the "through" terminating, either by breaking or by finishing the "through" send.  It c an then be reapplied on every "through".

The final problem is what to do in the overridden value[:value*] methods.  These should call some common helper that contacts the debugger.  The debugger can then morph the block back into a normal block and step into its activation.

N.B.
It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.  And tackling the two issues together (speeding up "through", and fixing stepping over/into Generators) might lead you to come up with a nice mini-framework for intercepting crucial execution transitions in the debugger.  Clearly a better solution to fork than killing simulation with primitive 19  is to open another debugger, or offer to open a new debugger, on the new process.  But one can see issues here.  There might be a rationale for a debugger with training wheels for learners exploring the system, and a "oh my god, it's covered in hair!" full featured debugger for us seasoned old hacks.

HTH

Best,

Christoph

HNY

_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

Christoph Thiede

Hi Eliot, thanks for your message! :-)


It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.


Yes, that is exactly what I proposed in http://forum.world.st/BUG-REGRESSION-while-debugging-Generator-nextPut-tp5108125p5109109.html. The VM appears not to like this, but if we could ensure the lifespan of such a DebuggedContext is restricted to debugging time, this should be fine. The only advantage I could imagine at the moment would be that such a subclass would make it even harder to find errors in the "non-debugging" machinery.

Btw, if you could take a look at the changeset I proposed there, it would be great!


Apart from this, according to my original question of this thread, I would actually expect "Through" not to search for blocks only, but for any context activations. What about you?

(However, from theory, we would only need to override #doPrimitive:method:receiver:args:.)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Eliot Miranda <[hidden email]>
Gesendet: Montag, 6. Januar 2020 22:53:32
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Debugger Through slow
 
Hi Christoph,

On Wed, Sep 11, 2019 at 4:55 AM Thiede, Christoph <[hidden email]> wrote:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


The way we did it in VisualWorks is to create subclasses of the various BlockClosure classes (in our case of BlockClosure and FullBlockClosure) that override the value[:value*] messages to call back into the debugger, and use adoptInstance: to convert the blocks created in the current activation into these "breaking" blocks.  

The first problem is identifying the set of blocks that need to be morphed into "through" breaking blocks (TBBs for the purposes of this email).
One way would be to simply use [Full]BlockClosure>>allInstances, selecting those whose home is the home context, but that could suck in large images.
Another way would be to somehow intercept block creation while stepping.sending and, say, maintain a dictionary in the debugger from home context to blocks whose home is that context.
IIRC, the VW implementation scanned the outgoing arguments at point of send (from a "through"), looking for blocks.  This is simple but misses cases where blocks are stored in variables, etc.

The second problem is when to do the morphing.  It should be done during the "through" processing, and undone on the "through" terminating, either by breaking or by finishing the "through" send.  It c an then be reapplied on every "through".

The final problem is what to do in the overridden value[:value*] methods.  These should call some common helper that contacts the debugger.  The debugger can then morph the block back into a normal block and step into its activation.

N.B.
It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.  And tackling the two issues together (speeding up "through", and fixing stepping over/into Generators) might lead you to come up with a nice mini-framework for intercepting crucial execution transitions in the debugger.  Clearly a better solution to fork than killing simulation with primitive 19  is to open another debugger, or offer to open a new debugger, on the new process.  But one can see issues here.  There might be a rationale for a debugger with training wheels for learners exploring the system, and a "oh my god, it's covered in hair!" full featured debugger for us seasoned old hacks.

HTH

Best,

Christoph

HNY

_,,,^..^,,,_
best, Eliot


Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

Eliot Miranda-2
Hi Christoph,

On Mon, Jan 6, 2020 at 2:30 PM Thiede, Christoph <[hidden email]> wrote:

Hi Eliot, thanks for your message! :-)


you're most welcome.

It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.


Yes, that is exactly what I proposed in http://forum.world.st/BUG-REGRESSION-while-debugging-Generator-nextPut-tp5108125p5109109.html. The VM appears not to like this, but if we could ensure the lifespan of such a DebuggedContext is restricted to debugging time, this should be fine.

Yes, I can imagine that adpoptInstance: doesn't divorce/make single contexts, so I may have some work to do.

The only advantage I could imagine at the moment would be that such a subclass would make it even harder to find errors in the "non-debugging" machinery.

Btw, if you could take a look at the changeset I proposed there, it would be great!

 
 I'll look at the change set asap (busy for the next few days).  

Apart from this, according to my original question of this thread, I would actually expect "Through" not to search for blocks only, but for any context activations. What about you?


What is achieved by searching for context activations? 


(However, from theory, we would only need to override #doPrimitive:method:receiver:args:.)


That doesn't make sen=ce to me.  The basic idea behind speeding up "through" is to use the same machinery as "step", which is based on per4form: rather than simulation.  Within the execution of a perform:... doPrimitive:method:receiver:args: is not used; instead value[:value*] messages are sent to blocks.  So the way we intercept these is by morphing blocks whose home is the context we're debugging into TBB's.  Does that make sense?


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Eliot Miranda <[hidden email]>
Gesendet: Montag, 6. Januar 2020 22:53:32
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Debugger Through slow
 
Hi Christoph,

On Wed, Sep 11, 2019 at 4:55 AM Thiede, Christoph <[hidden email]> wrote:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


The way we did it in VisualWorks is to create subclasses of the various BlockClosure classes (in our case of BlockClosure and FullBlockClosure) that override the value[:value*] messages to call back into the debugger, and use adoptInstance: to convert the blocks created in the current activation into these "breaking" blocks.  

The first problem is identifying the set of blocks that need to be morphed into "through" breaking blocks (TBBs for the purposes of this email).
One way would be to simply use [Full]BlockClosure>>allInstances, selecting those whose home is the home context, but that could suck in large images.
Another way would be to somehow intercept block creation while stepping.sending and, say, maintain a dictionary in the debugger from home context to blocks whose home is that context.
IIRC, the VW implementation scanned the outgoing arguments at point of send (from a "through"), looking for blocks.  This is simple but misses cases where blocks are stored in variables, etc.

The second problem is when to do the morphing.  It should be done during the "through" processing, and undone on the "through" terminating, either by breaking or by finishing the "through" send.  It c an then be reapplied on every "through".

The final problem is what to do in the overridden value[:value*] methods.  These should call some common helper that contacts the debugger.  The debugger can then morph the block back into a normal block and step into its activation.

N.B.
It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.  And tackling the two issues together (speeding up "through", and fixing stepping over/into Generators) might lead you to come up with a nice mini-framework for intercepting crucial execution transitions in the debugger.  Clearly a better solution to fork than killing simulation with primitive 19  is to open another debugger, or offer to open a new debugger, on the new process.  But one can see issues here.  There might be a rationale for a debugger with training wheels for learners exploring the system, and a "oh my god, it's covered in hair!" full featured debugger for us seasoned old hacks.

HTH

Best,

Christoph

HNY

_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Debugger Through slow

Christoph Thiede

Hi Eliot,


 I'll look at the change set asap (busy for the next few days).  


Don't hurry :)

What is achieved by searching for context activations? 

For example, do this:

ctxt := [thisContext copy] value.
ctxt jump "Step through jump"

In this case, I would indeed expect get back into the block. However, it is *not* activated again via #value.
I admit this is not a very common scenario, but as an edge case, it can help to identify our expectations - and mine would be exactly what the current implementation does.
Other folks here, what is your opinion?

> > (However, from theory, we would only need to override #doPrimitive:method:receiver:args:.)
> That doesn't make sen=ce to me.  The basic idea behind speeding up "through" is to use the same machinery as "step", which is based on per4form: rather than simulation.  Within the execution of a perform:... doPrimitive:method:receiver:args: is not used; instead value[:value*] messages are sent to blocks.  So the way we intercept these is by morphing blocks whose home is the context we're debugging into TBB's.  Does that make sense?

Yeah, you're right, I was wrong. Hm ... personally I don't know whether this optimization is worth these design changes (however smart they might be). If we put Context >> #step in a critical block or something similar, one could simply Cmd-dot if Through takes too much time, and then we would only need to update the debugger to show the latest step. What do you think about this?

(Apart from this, I would appreciate a DebuggedContext for the #runUntilErrorOrReturnFrom: issue. But imho, not a new class of this weight for optimization only ...)

Best,
Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Eliot Miranda <[hidden email]>
Gesendet: Dienstag, 7. Januar 2020 02:20:13
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Debugger Through slow
 
Hi Christoph,

On Mon, Jan 6, 2020 at 2:30 PM Thiede, Christoph <[hidden email]> wrote:

Hi Eliot, thanks for your message! :-)


you're most welcome.

It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.


Yes, that is exactly what I proposed in http://forum.world.st/BUG-REGRESSION-while-debugging-Generator-nextPut-tp5108125p5109109.html. The VM appears not to like this, but if we could ensure the lifespan of such a DebuggedContext is restricted to debugging time, this should be fine.

Yes, I can imagine that adpoptInstance: doesn't divorce/make single contexts, so I may have some work to do.

The only advantage I could imagine at the moment would be that such a subclass would make it even harder to find errors in the "non-debugging" machinery.

Btw, if you could take a look at the changeset I proposed there, it would be great!

 
 I'll look at the change set asap (busy for the next few days).  

Apart from this, according to my original question of this thread, I would actually expect "Through" not to search for blocks only, but for any context activations. What about you?


What is achieved by searching for context activations? 


(However, from theory, we would only need to override #doPrimitive:method:receiver:args:.)


That doesn't make sen=ce to me.  The basic idea behind speeding up "through" is to use the same machinery as "step", which is based on per4form: rather than simulation.  Within the execution of a perform:... doPrimitive:method:receiver:args: is not used; instead value[:value*] messages are sent to blocks.  So the way we intercept these is by morphing blocks whose home is the context we're debugging into TBB's.  Does that make sense?


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Eliot Miranda <[hidden email]>
Gesendet: Montag, 6. Januar 2020 22:53:32
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] Debugger Through slow
 
Hi Christoph,

On Wed, Sep 11, 2019 at 4:55 AM Thiede, Christoph <[hidden email]> wrote:

Hi all,


take the following snippet, debug-it and press "Through":

SqueakMessageCategoriesHelp asHelpTopic.


For me, it makes the debugger hang really long time, as apparently the whole code execution is simulated, searching for the current context (#stepToHome:). "Over", in contrast, is faster by far, calling #completeStep: instead.

Can we speed up "Through" in any way? As the button is explained as "Step into a block", we could call #completeStep: internally if the selected message does not contain a block argument, for example.


The way we did it in VisualWorks is to create subclasses of the various BlockClosure classes (in our case of BlockClosure and FullBlockClosure) that override the value[:value*] messages to call back into the debugger, and use adoptInstance: to convert the blocks created in the current activation into these "breaking" blocks.  

The first problem is identifying the set of blocks that need to be morphed into "through" breaking blocks (TBBs for the purposes of this email).
One way would be to simply use [Full]BlockClosure>>allInstances, selecting those whose home is the home context, but that could suck in large images.
Another way would be to somehow intercept block creation while stepping.sending and, say, maintain a dictionary in the debugger from home context to blocks whose home is that context.
IIRC, the VW implementation scanned the outgoing arguments at point of send (from a "through"), looking for blocks.  This is simple but misses cases where blocks are stored in variables, etc.

The second problem is when to do the morphing.  It should be done during the "through" processing, and undone on the "through" terminating, either by breaking or by finishing the "through" send.  It c an then be reapplied on every "through".

The final problem is what to do in the overridden value[:value*] methods.  These should call some common helper that contacts the debugger.  The debugger can then morph the block back into a normal block and step into its activation.

N.B.
It comes to mind that a similar trick might be usable to fix the swapSender:/runIUntilErrorOrReturmFrom: misinteraction.  One could change the class of the current context into one that overrides all sender setting methods (in particular swapSender:).  That could be a cool solution.  And tackling the two issues together (speeding up "through", and fixing stepping over/into Generators) might lead you to come up with a nice mini-framework for intercepting crucial execution transitions in the debugger.  Clearly a better solution to fork than killing simulation with primitive 19  is to open another debugger, or offer to open a new debugger, on the new process.  But one can see issues here.  There might be a rationale for a debugger with training wheels for learners exploring the system, and a "oh my god, it's covered in hair!" full featured debugger for us seasoned old hacks.

HTH

Best,

Christoph

HNY

_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot


Carpe Squeak!