Debugging tip for stepping through code wrapped in an #execLongOperation:message:* block

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

Debugging tip for stepping through code wrapped in an #execLongOperation:message:* block

Bob Brodd
If your application uses the #execLongOperation:message:* variety of methods to take advantage of the mechanism to display a progress bar while a long running operation is in progress, you probably have experienced the joys of trying to debug the code wrapped up in the block.  When a break point is hit , about all  you can do is inspect the current state of objects, but you can not continue stepping though the code.

Before I discovered the secret to debugging such code blocks, I used to go so far as to comment out my call to the execLongOperation:message:* statement so that I could step through the code.  This approach works, but there is a better way that does not involve modifying your code; and better yet, it already exists in your image (though if running pre 8.6 code, you will have to apply a fix .. see below).

The secret is to execute the following snippet of code before running the code that kicks off the long operation:

EtWindow execLongOperationsInBackground: false.
When this value is false, the code block never gets forked onto the background process, so the debugger is able to step through the code in normal fashion.

If you are running versions of VA Smalltalk prior to 8.6, you will need to modify the EtWindow>>#execLongOperation:message:allowCancel:showProgress: 
method to avoid a bug where the operation runs once in the UI process, then again in a background process.  There is one occurrence of the following snippet of code in this method: 

self #execShortOperation: runBlock .  
The code should be preceded by a return (^) character so that the code block does not run again in a background process:
^ self #execShortOperation: runBlock .
Enjoy the beauty of debugging Smalltalk code even more!
Bob

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Debugging tip for stepping through code wrapped in an #execLongOperation:message:* block

Richard Sargent
Administrator
On Wednesday, February 24, 2016 at 11:10:10 AM UTC-8, Bob Brodd wrote:
If your application uses the #execLongOperation:message:* variety of methods to take advantage of the mechanism to display a progress bar while a long running operation is in progress, you probably have experienced the joys of trying to debug the code wrapped up in the block.  When a break point is hit , about all  you can do is inspect the current state of objects, but you can not continue stepping though the code.

Before I discovered the secret to debugging such code blocks, I used to go so far as to comment out my call to the execLongOperation:message:* statement so that I could step through the code.  This approach works, but there is a better way that does not involve modifying your code; and better yet, it already exists in your image (though if running pre 8.6 code, you will have to apply a fix .. see below).

The secret is to execute the following snippet of code before running the code that kicks off the long operation:

EtWindow execLongOperationsInBackground: false.
When this value is false, the code block never gets forked onto the background process, so the debugger is able to step through the code in normal fashion.

Thanks for that information, Bob. It's great advice!
(I wish I had thought to look into what was being executed all these years. *sigh*)

Do you happen to know why the runBlock is invoked with #atEndOrWhenExceptionDo: instead of something more conventional like #ensure:? It would be nice if the implementation waited for the process to be terminated (by correcting the error, killing the process, etc.). Is there something that prevents that?

Failing that, it would help if that expression were hooked up to a menu on the Transcript, for example. :-)


If you are running versions of VA Smalltalk prior to 8.6, you will need to modify the EtWindow>>#execLongOperation:message:allowCancel:showProgress: 
method to avoid a bug where the operation runs once in the UI process, then again in a background process.  There is one occurrence of the following snippet of code in this method: 

self #execShortOperation: runBlock .  
The code should be preceded by a return (^) character so that the code block does not run again in a background process:
^ self #execShortOperation: runBlock .
Enjoy the beauty of debugging Smalltalk code even more!
Bob

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Debugging tip for stepping through code wrapped in an #execLongOperation:message:* block

Bob Brodd


On Wednesday, February 24, 2016 at 7:30:29 PM UTC-5, Richard Sargent wrote:
On Wednesday, February 24, 2016 at 11:10:10 AM UTC-8, Bob Brodd wrote:
If your application uses the #execLongOperation:message:* variety of methods to take advantage of the mechanism to display a progress bar while a long running operation is in progress, you probably have experienced the joys of trying to debug the code wrapped up in the block.  When a break point is hit , about all  you can do is inspect the current state of objects, but you can not continue stepping though the code.

Before I discovered the secret to debugging such code blocks, I used to go so far as to comment out my call to the execLongOperation:message:* statement so that I could step through the code.  This approach works, but there is a better way that does not involve modifying your code; and better yet, it already exists in your image (though if running pre 8.6 code, you will have to apply a fix .. see below).

The secret is to execute the following snippet of code before running the code that kicks off the long operation:

EtWindow execLongOperationsInBackground: false.
When this value is false, the code block never gets forked onto the background process, so the debugger is able to step through the code in normal fashion.

Thanks for that information, Bob. It's great advice!
(I wish I had thought to look into what was being executed all these years. *sigh*)
I hear ya .... I spent too many years working around this issue too.

Do you happen to know why the runBlock is invoked with #atEndOrWhenExceptionDo: instead of something more conventional like #ensure:? It would be nice if the implementation waited for the process to be terminated (by correcting the error, killing the process, etc.). Is there something that prevents that?
 
I am pretty certain that when this method was created, the ensure: protocol did not exist.  We have a todo work item to change usage of #atEndOrWhenExceptionDo: to #ensure, but it is not a scheduled item yet.  As for waiting for the process to be terminated, etc.  , I am not really sure.  I do see comments like "We rely on the fact that the exceptions can not be resumed." 

Failing that, it would help if that expression were hooked up to a menu on the Transcript, for example. :-)
 
Good idea for sure.  If I go long enough without using this tip, I forget what class to send the message to, or exactly what the method name is,  and have to look it up again. 


If you are running versions of VA Smalltalk prior to 8.6, you will need to modify the EtWindow>>#execLongOperation:message:allowCancel:showProgress: 
method to avoid a bug where the operation runs once in the UI process, then again in a background process.  There is one occurrence of the following snippet of code in this method: 

self #execShortOperation: runBlock .  
The code should be preceded by a return (^) character so that the code block does not run again in a background process:
^ self #execShortOperation: runBlock .
Enjoy the beauty of debugging Smalltalk code even more!
Bob

--
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/va-smalltalk.
For more options, visit https://groups.google.com/d/optout.