[squeak-dev] Bug in Process>>#terminate | Returning from unwind contexts

Christoph Thiede christoph.thiede at student.hpi.uni-potsdam.de
Tue Mar 16 13:36:37 UTC 2021


Hi Jaromir,

again, very sorry for keeping you waiting for so long time.

I'll try to go through your questions step by step, hoping everything is
still relevant: :-)

> It seems to me after `ctxt restart` the thread never returns back so the
> assignment is moot?

Fair question. After evaluating "[self error] ensure: [^1]", abandoning the
debugger, and raising another error, the relevant #terminate context is
indeed dead, so somehow the "ctxt restart" appears to have returned indeed
... But I don't know why. :)

(By the way, in case you did not yet find this out by yourself, you can find
the activated #terminate context by exploring the second-bottommost context
(#ensure:) of the UI process and navigating up in the sender stack of its
aBlock argument's outerContext ...

<http://forum.world.st/file/t372205/inspect_%23terminate.png> )

> At any rate it seems to me the problem is not related to non-local returns
> exclusively. Other scenario I have now:
> x:=nil. [self error: 'x1'] ensure: [[self error: 'x2'] ensure: [[self
> error: 'x3'] ensure: [x:=3]. x:=2]. x:=1].
> x

Oh no. Important findings, though! This enlarges the issue we are discussing
here. Returning from unwind contexts *could* be considered as something
stupid and illegal as I wrote above, but raising errors from them is
something much more likely. Even non-Smalltalkish languages such as Python
support this and receiving unwind errors in these situations has always
appeared as a sad limitation to me.

Hm ... in this example, my changeset raises a #cannotReturn: after
abandoning all the debuggers. :/

((Side note: Maybe we should tackle ExceptionTests>>testHandlerFromAction
these days, too. However, not sure whether they are later to each other,
thus the double brackets :)))

> If you Abandon the FIRST error debugger - do you expect to continue to the
> second debugger, abandon it and continue to the third debugger or rather
> quit right after the FIRST debugger Abandon? If the former then what would
> the difference between Proceed and Abandon be?

In my mental model, these debuggers form a (virtual) stack. Maybe thinks
would get clearer if we would only delete the debugger window after the
termination had been completed. I tell the first debugger to abandon -
during the abandoning, another error occurs, and a second debugger informs
me about this incident - I tell it to abandon, too - so what exactly did I
abandon now? The unwind handling (i.e. a single unwind block) or rather the
unwinding activity itself (which would be equivalent to continue the regular
execution)? Let's assume the first one for now ... And finally, the third
debugger appears because a second unwind block raised an error - I tell it
to continue, meaning that the unwind handling should be resumed right from
the place where the error has occurred, so in the end, the termination
should be continued. Phew! What do you think about this example? ;-)

> What is the expected semantics of the Debugger's Abandon? To quit and do
> nothing more to the debugged process or continue unwinding?

I have to agree with Levente here that unwinding should not be skipped here
definitively. Abandoning is used every often when an error occurs and it's a
fundamental meaning of #ensure: contexts to be executed even if the regular
execution is not being continued, giving their senders the chance to clean
up things.

And regarding your proposal of enforcing termination:

> >>> [interruptedProcess isTerminated] whileFalse: [interruptedProcess
terminate].

I'm not sure whether this would be a good idea, though ... The debugger is
only a graphical tool that makes process control more easily. IMHO Debugger
>> #abandon should have exactly the same effect as Process >> #terminate.

So the next question would be whether we would want such an enforce loop
directly in Processor >> #terminate. I don't know.

tl;dr: Unwind errors are a problem, but my proposed changeset is not really
suitable to fix all of them. Should we probably just stick with the
UnhandledError handling from within Process >> #terminate? This only seems
to be necessary for calls from the Debugger (see Debugger >> #stepOver).
And with regard to the returns from unwind contexts, here is another vague
idea: Could it help us in any way to raise a second exception from
#aboutToReturn:through: to keep senders such as Process >> #terminate
informed? Or would this just be unnecessary? We already appear to have used
ExceptionAboutToReturn in the past. Can anyone remember its story? Maybe
nested unwinding even has worked better in past Squeak versions before it
has been removed?
Hm ...
I have the feeling that finding a better solution for this problem will keep
occupying us for some more time. Maybe you have some other great ideas! :-)

Best,
Christoph



-----
Carpe Squeak!
--
Sent from: http://forum.world.st/Squeak-Dev-f45488.html


More information about the Squeak-dev mailing list