Replacing a StandardToolSet

Igor Stasenko siguctua at gmail.com
Wed Feb 6 18:06:55 UTC 2008


Thanks for answer :)

On 06/02/2008, Tom Phoenix <rootbeer at redcat.com> wrote:
> On Feb 6, 2008 12:21 AM, Igor Stasenko <siguctua at gmail.com> wrote:
>
> > i'm stuck with a code to handle errors in squeak image.
> > I want to replace the default behavior, when unhandled error occurs is
> > to same as user pressing 'Abort' button.
> >
> > This is a code snippet, how i doing this:
> >
> > ----
> > HydraDebugToolSet>>debugError: anError
> >         recursed == true ifTrue: [ ^ Processor terminateActive ].
> >         recursed := true.
> >
> >         Transcript show: 'Error in interpreter (', HydraVM
> > myInterpreterInstance asString , ')',
> >                 String cr,
> >                 anError description,
> >                 String cr,
> >                 anError signalerContext shortStack.
> >
> >         Smalltalk
> >                 logError: anError description
> >                 inContext: anError signalerContext
> >                 to: 'HydraDebug.log'.
> >
> >         recursed := false.
> >         Processor terminateActive.
> >         ^ nil
>
> There's something about that variable 'recursed' that smells wrong. I
> think it's that you're trying to make your code reentrant, but you're
> not testing and setting that flag atomically. Maybe you need to use a
> Semaphore?
>

Well, it's a dead-simple inst var. I do a little care if it's set
non-atomically.
Event if error will recurse for a couple of times, not a big deal.
The main reason of having it,  is to prevent infinite recursion in a long term.
But you highlighted another problem: given code is not thread-safe.
If scheduler will decide to stop in the middle of error handling and
switch to another process, where error will occur too, this could lead
to problems.
So, in perfect, error handling code should be guarded by semaphore.
Also, i would recommend doing same for main squeak image.

> > The problem in doing Processor terminateActive - i'm not sure if this
> > works exactly as abandoning process.
> > And i'm stuck, because if i don't put Processor terminateActive, then
> > it starts an infinite loop barfing on sending unknown message to nil
> > (i suspect that it's because i returning nil at exit).
>
> Exactly; you need to make a method that, unlike any normal method,
> never returns. Part of the trouble is that sometimes the current
> process is the UI process, which needs to be replaced before it's
> terminated. I think you need to end your method with something like
> this:
>
>     Project spawnNewProcessIfThisIsUI: Processor activeProcess.
>     Processor terminateActive.  "stop here"
>     ^self error: 'This line should never be reached.'.
>
> I'm not completely sure whether that is the Right Thing to Do in all
> circumstances, especially under the Hydra VM. Does that work for you?
> Good luck with it!
>

You're right, except that, i don't have UI process in non-interactive
image, because it pointless to have it. :)
I stubbed out the code by replacing UIManager to simply produce error
at any attempt when something tries to use UI.
And HydraDebugToolSet class, which handles errors should simply put
message to transcript, again, without involving any UI (popping up
debugger e.t.c).

Any attempt to use UI in non-interactive image, currently leads to
error (due to primitives failure).
So, mainly, i was in need of this class to see, if background image
starts cleanly , by checking what errors it produces during startup.

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list