[Vm-dev] Image freeze because handleTimerEvent and Seaside process gone?!

Adrian Lienhard adi at netstyle.ch
Thu Dec 30 22:50:00 UTC 2010


Thanks Andreas and David for the responses!

In the meantime I've gathered more information. From the mail of Andreas I assumed that the most likely reason for the freeze is that the timer event loop throws an unhandled exception and therefore gets suspended.

So I added a guard to catch any error in handleTimerEvent, restart the loop, and then pass the exception to open a debugger:
 
runTimerEventLoop
	[RunTimerEventLoop] whileTrue: [
		[ self handleTimerEvent ]
			on: Error
			do: [ :e |
				self startTimerEventLoop.
				...write a warning to stdout...
				e pass ] ]

And voila, after 10 days or so I got the stack trace below.

I haven't had time to dive into it, but from the stack it seems like a concurrency issue in linked list (although I wonder whether that's possible since the timer event loop runs at the highest priority...). 

Maybe something catches somebody's eye.

Cheers,
Adrian


THERE_BE_DRAGONS_HERE
Error: no such method!
30 December 2010 10:32:28 pm

VM: unix - i686 - linux - Squeak3.10.2 of '5 June 2008' [latest update: #7179]
Image: Pharo1.1 [Latest update: #11410]

Semaphore(Object)>>error:
	Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Arguments and temporary variables: 
		t1: 	'no such method!'
	Receiver's instance variables: 
		firstLink: 	a Process in [] in DelayWaitTimeout>>wait
		lastLink: 	a Process in [] in DelayWaitTimeout>>wait
		excessSignals: 	0


[] in Semaphore(LinkedList)>>removeLink:
	Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Arguments and temporary variables: 

	Receiver's instance variables: 
		firstLink: 	a Process in [] in DelayWaitTimeout>>wait
		lastLink: 	a Process in [] in DelayWaitTimeout>>wait
		excessSignals: 	0


Semaphore(LinkedList)>>removeLink:ifAbsent:
	Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Arguments and temporary variables: 
		aLink: 	a Process in [] in DelayWaitTimeout>>wait
		aBlock: 	[self error: 'no such method!']
		tempLink: 	nil
	Receiver's instance variables: 
		firstLink: 	a Process in [] in DelayWaitTimeout>>wait
		lastLink: 	a Process in [] in DelayWaitTimeout>>wait
		excessSignals: 	0


Semaphore(LinkedList)>>removeLink:
	Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Arguments and temporary variables: 
		aLink: 	a Process in [] in DelayWaitTimeout>>wait
	Receiver's instance variables: 
		firstLink: 	a Process in [] in DelayWaitTimeout>>wait
		lastLink: 	a Process in [] in DelayWaitTimeout>>wait
		excessSignals: 	0


Semaphore(LinkedList)>>remove:ifAbsent:
	Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Arguments and temporary variables: 
		aLinkOrObject: 	a Process in [] in DelayWaitTimeout>>wait
		aBlock: 	[]
		link: 	a Process in [] in DelayWaitTimeout>>wait
	Receiver's instance variables: 
		firstLink: 	a Process in [] in DelayWaitTimeout>>wait
		lastLink: 	a Process in [] in DelayWaitTimeout>>wait
		excessSignals: 	0


Process>>suspend
	Receiver: a Process in [] in DelayWaitTimeout>>wait
	Arguments and temporary variables: 
		t1: 	a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
	Receiver's instance variables: 
		nextLink: 	nil
		suspendedContext: 	[] in DelayWaitTimeout>>wait
		priority: 	30
		myList: 	a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
		errorHandler: 	nil
		name: 	'seaside'
		env: 	nil


DelayWaitTimeout>>signalWaitingProcess
	Receiver: a DelayWaitTimeout(10000 msecs)
	Arguments and temporary variables: 

	Receiver's instance variables: 
		delayDuration: 	10000
		resumptionTime: 	217048389
		delaySemaphore: 	a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
		beingWaitedOn: 	false
		process: 	a Process in [] in DelayWaitTimeout>>wait
		expired: 	true


Delay class>>handleTimerEvent
	Receiver: Delay
	Arguments and temporary variables: 
		t1: 	217128602
		t2: 	nil
	Receiver's instance variables: 
		superclass: 	Object
		methodDict: 	a MethodDictionary(#adjustResumptionTimeOldBase:newBase:->(Delay>>#...etc...
		format: 	138
		instanceVariables: 	#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWa...etc...
		organization: 	('as yet unclassified' adjustResumptionTimeOldBase:newBase: being...etc...
		subclasses: 	{MonitorDelay. DelayWaitTimeout}
		name: 	#Delay
		classPool: 	a Dictionary(#AccessProtect->a Semaphore() #ActiveDelay->a Delay(10 ...etc...
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Kernel-Processes'
		traitComposition: 	{}
		localSelectors: 	nil


[] in Delay class>>runTimerEventLoop
	Receiver: Delay
	Arguments and temporary variables: 

	Receiver's instance variables: 
		superclass: 	Object
		methodDict: 	a MethodDictionary(#adjustResumptionTimeOldBase:newBase:->(Delay>>#...etc...
		format: 	138
		instanceVariables: 	#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWa...etc...
		organization: 	('as yet unclassified' adjustResumptionTimeOldBase:newBase: being...etc...
		subclasses: 	{MonitorDelay. DelayWaitTimeout}
		name: 	#Delay
		classPool: 	a Dictionary(#AccessProtect->a Semaphore() #ActiveDelay->a Delay(10 ...etc...
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Kernel-Processes'
		traitComposition: 	{}
		localSelectors: 	nil


BlockClosure>>on:do:
	Receiver: [self handleTimerEvent]
	Arguments and temporary variables: 
		exception: 	Error
		handlerAction: 	[:e | 
self startTimerEventLoop.
	FileStream
		fileNamed: '/dev/...etc...
		handlerActive: 	false
	Receiver's instance variables: 
		outerContext: 	Delay class>>runTimerEventLoop
		startpc: 	108
		numArgs: 	0


Delay class>>runTimerEventLoop
	Receiver: Delay
	Arguments and temporary variables: 

	Receiver's instance variables: 
		superclass: 	Object
		methodDict: 	a MethodDictionary(#adjustResumptionTimeOldBase:newBase:->(Delay>>#...etc...
		format: 	138
		instanceVariables: 	#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWa...etc...
		organization: 	('as yet unclassified' adjustResumptionTimeOldBase:newBase: being...etc...
		subclasses: 	{MonitorDelay. DelayWaitTimeout}
		name: 	#Delay
		classPool: 	a Dictionary(#AccessProtect->a Semaphore() #ActiveDelay->a Delay(10 ...etc...
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Kernel-Processes'
		traitComposition: 	{}
		localSelectors: 	nil


[] in Delay class>>startTimerEventLoop
	Receiver: Delay
	Arguments and temporary variables: 

	Receiver's instance variables: 
		superclass: 	Object
		methodDict: 	a MethodDictionary(#adjustResumptionTimeOldBase:newBase:->(Delay>>#...etc...
		format: 	138
		instanceVariables: 	#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWa...etc...
		organization: 	('as yet unclassified' adjustResumptionTimeOldBase:newBase: being...etc...
		subclasses: 	{MonitorDelay. DelayWaitTimeout}
		name: 	#Delay
		classPool: 	a Dictionary(#AccessProtect->a Semaphore() #ActiveDelay->a Delay(10 ...etc...
		sharedPools: 	nil
		environment: 	a SystemDictionary(lots of globals)
		category: 	#'Kernel-Processes'
		traitComposition: 	{}
		localSelectors: 	nil


[] in BlockClosure>>newProcess
	Receiver: [self runTimerEventLoop]
	Arguments and temporary variables: 

	Receiver's instance variables: 
		outerContext: 	Delay class>>startTimerEventLoop
		startpc: 	144
		numArgs: 	0



--- The full stack ---
Semaphore(Object)>>error:
[] in Semaphore(LinkedList)>>removeLink:
Semaphore(LinkedList)>>removeLink:ifAbsent:
Semaphore(LinkedList)>>removeLink:
Semaphore(LinkedList)>>remove:ifAbsent:
Process>>suspend
DelayWaitTimeout>>signalWaitingProcess
Delay class>>handleTimerEvent
[] in Delay class>>runTimerEventLoop
BlockClosure>>on:do:
Delay class>>runTimerEventLoop
[] in Delay class>>startTimerEventLoop
[] in BlockClosure>>newProcess
------------------------------------------------------------


More information about the Vm-dev mailing list