[squeak-dev] Re: DebuggerUnwindBug>>testUnwindDebuggerWithStep

Andreas Raab andreas.raab at gmx.de
Sat Jun 21 23:33:32 UTC 2008


So having looked more closely into this issue I am by now convinced that 
this is a bug in the simulation machinery. The point is that we're 
simulating stepping out of a semaphore wait, e.g.,

   sema := Semaphore new.
   process := [sema wait] forkAt: Processor activePriority + 1.
   ctx := process completeStep: process suspendedContext.

At this point we're out of the semaphore wait and consequently the 
suspendingList of the process should be nil but it ain't. I've attached 
two tests which illustrate the problem.

Cheers,
   - Andreas


Andreas Raab wrote:
> Hi Norbert -
> 
> Good find. The test is interesting since it illustrates behavior that 
> can *only* happen during simulation. Unless simulated, the return from 
> the preceding wait and the activation of the block are atomic so you'd 
> never be able to get into the spot that this particular test uses. The 
> test itself was intended to show a somewhat different problem but it 
> should be made to work since I don't see why one should't be able to 
> terminate the debugger in this spot and expect things to work. I'll have 
> to ponder this one a little since there are many implications there.
> 
> Cheers,
>   - Andreas
> 
> Norbert Hartl wrote:
>> This test case appears at some point to fail. It succeeds in 3.9.
>> I narrowed the problem to an update of 3.9.1 with update 7071
>> (Kernel-sd.151) which introduced it.
>> The piece of code that triggers it is:
>>
>> Process>>terminate
>> ...
>> suspendedContext ifNotNil: [
>>    "Figure out if we are terminating the process while waiting in   
>>     Semaphore>>critical: In this case, pop the suspendedContext so that
>>     we leave the ensure: block inside Semaphore>>critical: without
>>     signaling the semaphore."
>>       (inSema == true and:[
>>          suspendedContext method == (
>>             Semaphore compiledMethodAt: #critical:) ]) ifTrue:[
>>                suspendedContext := suspendedContext home.
>>          ].
>> ...
>>
>> I don't really understand the rationale behind doing this but it
>> seems that it conflicts with the test assumption:
>>
>> DebuggerUnwindBug>>testUnwindDebuggerWithStep
>> ...
>>    debugger doStep.
>>    "close debugger"
>>    top delete.
>>
>>    "and see if unwind protection worked"
>>    self assert: sema isSignaled.
>>
>> As I don't really understand what happens and what should happen I would
>> be glad to hear some words of advice.
>>
>> Norbert
>>
>>
>>
> 
> 
> 

-------------- next part --------------
'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 21 June 2008 at 4:32:05 pm'!
TestCase subclass: #SimulationBugs
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'KernelTests-Processes'!

!SimulationBugs methodsFor: 'tests' stamp: 'ar 6/21/2008 16:31'!
testStepOutOfCriticalAndTerminate
	"Illustrates a bug in the simulation of stepping out of Semaphore>>critical:."
	| sema process ctx newCtx |
	sema := Semaphore forMutualExclusion.
	self assert: sema isSignaled.
	process := [sema critical:[sema wait]] forkAt: Processor activePriority + 1.
	self deny: sema isSignaled.
	"At this point the process should have myList set to sema"
	self assert: process suspendingList == sema.
	"Now step out of the wait and back into critical:"
	ctx := process suspendedContext.
	[ctx method == (Semaphore compiledMethodAt: #critical:)] whileFalse:[
		newCtx := process completeStep: ctx.
		newCtx = ctx ifTrue:[process stepToSendOrReturn].
		ctx := newCtx.
	].
	"At this point, terminating the process should leave the semaphore signaled"
	process terminate.
	self assert: sema isSignaled.! !

!SimulationBugs methodsFor: 'tests' stamp: 'art 6/21/2008 16:26'!
testStepOutOfSemaphoreWait
	"Illustrates a bug in the simulation of stepping out of Semaphore>>wait.
	A simplified version for testStepOutOfCriticalAndTerminate."
	| sema process |
	sema := Semaphore new.
	process := [sema wait] forkAt: Processor activePriority + 1.
	"At this point the process should have myList set to sema"
	self assert: process suspendingList == sema.
	"Now step out of the wait"
	process completeStep: process suspendedContext.
	"At this point we expect myList to be nil since we're no longer waiting on the semaphore"
	self assert: process suspendingList == nil.
! !


More information about the Squeak-dev mailing list