Hello again,
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 ---------- 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). But if i leave process termination , then interpreter exits very early blaming me, that there is no scheduled processes left. Does it means, that all processes in image stepped on error and i killed them, or it just means, that there is no processes which can be scheduled at current point of time (some can wait on semaphore for external event occur). Can anyone, please, advice, how to make this stinky code to work without causing troubles? -- Best regards, Igor Stasenko AKA sig. |
On Feb 6, 2008 12:21 AM, Igor Stasenko <[hidden email]> 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? > 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! --Tom Phoenix |
Thanks for answer :)
On 06/02/2008, Tom Phoenix <[hidden email]> wrote: > On Feb 6, 2008 12:21 AM, Igor Stasenko <[hidden email]> 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. |
Free forum by Nabble | Edit this page |