-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unhandled Win32 Exception on primitiveQuit #128
Comments
Another thing that I don´t understand and annoys me is why using a deferred evaluation works sometimes and others not? We have changed the quit: method as below:
You could think that it's enough to solve the problem because the quit will be routed trough the VM's main interpret loop but sometimes fails in the same way. |
I'm not surprised you get unpredictable effects with DeferredValues, these are a kind of promise and fork a process that will execute the operation fairly non-deterministically. As there is only a single OS thread in use, it might be inside a callback when a context switch is made to the DeferredValue process, so the the quit primitive will fail in the same way.
|
Unfortunately, handling the Win32 exception in the callbackTerminationFilter as proposed above would not be the right fix. It will "work", but would really defeat the object of quitting this way in the first place. It would be similar to just calling the exit function directly. The objective is to unwind the stack cleanly, although that only really matters when running Dolphin in-proc. |
About the callbackTerminationFilter: I suspected you would would tell me that :) And for the workaround for the primQuit: I'm feeling very dumb, because I thought deferredValue were doing the same as postToInputQueue. I forgotten the postToInputQueue message at all. I'm not doing Smalltalk these days so my head is throwing things out. I've tested with a debug vm and works ok so I'm pretty confident it'll work as well in the runtime environment. I let you know. |
Using the same code as the recently added to the base image for dolphinsmalltalk/Dolphin#355 we can't no longer reproduce this error. |
Closing based on comment from @fxgallego that the workaround solves the issue. |
I'm copying here the excelent description to this problem by @blairmcg in this comment
The simplest way to reproduce this is evaluating
SessionManager current quit: 0
At the VM level it's easy to see what's happening (inspired by the Blair comment).
If you halt the primitiveQuit and step trough code you can follow this path:
1. primitiveQuit
2. exitSmalltalk
3. DolphinExit
4. RaiseFatalError
When a normal image exits occurs (for example when user clicks the main shell close button) the primitiveQuit is executed and signals an exception as you can see in the code above.
The exception is managed in the handler block of the VMRun function in
dolphin.cpp
and initiates the Dolphin's vm clean shutdown process as you can see below:But when the primitiveQuit is executed trough a callback (or during a callback?) the quit exception is handled in other function, an exception filter in the function
Interpreter::callback
in fileInterfac.cpp
.The exception filter (hanlder?) code is implemented in the function
Interpreter::callbackTerminationFilter
, see below:There is no code to handle an exception case like the one generated by the primitiveQuit.
What if we can add an extra case to the above code in order to handle the quit exception doing the same stuff as in the VMRun handler? After all it's going to shutdown. Are there other cleanup blocks others than the ones in DolphinExitInstance()?
As a proof of concept I've added the extra case to this last handler as:
(The case value number is the quit exceptionCode and should be wrote in a more elegant way)
And it appears to work well. I don't know what other implications could have this hack.
Sorry but I'm not a C++ expert nor a VM engineer probably I'm wrong naming things in some parts of this report.
The text was updated successfully, but these errors were encountered: