Hi all, hi Eliot,
I have to revise my previous recommendation of the #basicEvaluate:onBehalfOf: solution. After taking another look at Jakob's example from above ([^ self halt] ensure: [1 asString]), I recognized that this approach would not fix the infinite debuggers in this situation. Here's the reason behind it:
When stepping over the '^ self halt' statement in the example, a #cannotReturn: message is invoked by the VM at some point where the stack looks somehow like this:
Context>>return:through: Context>>aboutToReturn:through: ... Context>>runUntilErrorOrReturnFrom: ... Process>>evaluate:onBehalfOf: ... Process>>complete: ... Debugger>>doStep
However, the fact that a #cannotReturn: has been invoked means that the stack has got corrupted during the execution, so no exception can be passed back to any exception handler that we might install in #evaluate:onBehalfOf:. For this reason, when the BlockCannotReturn handling reaches StandardToolSet >> #handleError:, the effectiveProcess is suspended instead of the original activeProcess, and the debuggers are bouncing again ...
Now you might argue that this situation is only the consequence of another error that occurs during the simulated execution of Context>>aboutToReturn:through: (because of the #runUntilErrorOrReturnFrom: hack, see http://forum.world.st/BUG-REGRESSION-while-debugging-Generator-gt-gt-nextPut...), but I constructed another example that is immune to the basicEvaluate:onBehalfOf: approach, too, but in this example the fault in this example is clearly located in the user code so a powerful debugger framework should not struggle about it:
[] ensure: [thisContext privSender: nil] "step over #ensure:"
And there is even a second problem with the basicEvaluate:onBehalfOf: process because I found two calls on Process >> #debug:title:full: from the simulator (Context) that do not even signal any exception before invoking the debugger on the activeProcess, so again, an exception handler in #basicEvaluate:onBehalfOf: would not be activated at all.
tl;dr: The basicEvaluate:onBehalfOf: approach, in spite of its simplicity, would not cover all situations that can lead to an infinite debugger situation. For this reason, I recommend to use my first approach instead, which was to define #basicActiveProcess and #isBasicActiveProcess on Process that ignore the effectiveProcess mock-up for the single purpose of suspending the correct process when a debugger is spawned in whatever way inside of an #evaluate:onBehalfOf: block.
Does this argument sound reasonable to you? :-) I have prepared some tests and an updated changeset and am looking forward to uploading it with your agreement.
Best, Christoph
-- Sent from: http://forum.world.st/Squeak-Dev-f45488.html