[squeak-dev] The broken user interrupt, or the saga of 100000 factorial.

Bert Freudenberg bert at freudenbergs.de
Thu Dec 15 10:35:55 UTC 2011


On 15.12.2011, at 02:51, Christopher Oliver wrote:

> I spent a bit of time working backwards from the user interrupt watcher process:
> 
> 	InputSensor>>userInterruptWatcher
> 	SmalltalkImage>>handleUserInterrupt
> 	MorphicProject>>interruptName:
> 	MorphicProject>>interruptName:preemptedProcess:
> 	Debugger class>>openInterrupt:onProcess:
> 	SmalltalkImage>>logSqueakError:inContext:
> 	SmalltalkImage>>logError:inContext:to:
> 	ContextPart>>errorReportOn:
> 	MethodContext>>printDetails:
> 	ContextPart>>tempsAndValuesLimitedTo:indent:
> 	Object>>printStringLimitedTo:
> 
> The story runs as follows: you're more than likely to interrupt '100000 factorial' in SmallInteger>>* since that's the bulk of the computation, and the argument aNumber is
> more than likely a LargePositiveInteger.  When ContextPart>>errorReportOn: displays
> this, the bignum is converted to a decimal string and then truncated, and this appears
> to be the source of the delay.  Nothing prior to or following the invocation of
> Object>>printStringLimitedTo: takes much time at all.  This suggests that vars in the
> first twenty frames (see ContextPart>>errorReportOn:) that have a string representation
> that's expensive to compute will make Smalltalk appear to hang on cmd-.  I can appreciate
> value in being able to look at the stack dump in SqueakDebug.log to determine where
> Smalltalk was when you hit the interrupt key, so I'm at a loss how is best to go here.
> 
> Thoughts?


Sounds tempting, but I don't think that is the core of the problem. Try this in Debugger>>openInterrupt:onProcess:

	Preferences logDebuggerStackToFile ifTrue:
		[[(aString includesSubString: 'Space') & (aString includesSubString: 'low')
			ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
			ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]
		] on: CurrentReadOnlySourceFiles do: [:ex | "ignore"]].

With this, interrupting factorial works fine. However, replacing it with this:

	Preferences logDebuggerStackToFile ifTrue:
		[[(aString includesSubString: 'Space') & (aString includesSubString: 'low')
			ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
			ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]
		] valueWithin: 200 milliSeconds onTimeout: []].

... does not let you interrupt factorial. 

And "[true] whileTrue" can't be interrupted even if logging is disabled. That seems like another problem though because in that tight loop, the image does not even get to process the interrupt.

- Bert -





More information about the Squeak-dev mailing list