[squeak-dev] Error: infinite recursion in doesNotUnderstand:

mail at jaromir.net mail at jaromir.net
Mon Jan 10 17:36:42 UTC 2022

Hi Christoph,

Eliot's fix raises the 'infinite recursion' only when you Proceed the debugger without any change, i.e. attempting to evaluate the same unknown message; what's the scenario you've had in mind and what am I missing here? :) 

Oh, wait - did you mean you'd defined the unknown method in the wrong class so it only looked like nothing changed?

In that case yes, #dnu will give you the 'infinite recursion' error because from it's point of view 'nothing changed'.

The 'infinite recursion' guard is nice to have to prevent infinite recursion when you work with an MNU inside the ensure argument block. #terminateAggressively avoids this recursion by skipping halfway unwound blocks; at a price though: I've recently noticed when you abandon the debugger with a process inside a critical section of a conditional variable (Mutex, Semaphore) it wouldn't release the critical section: it would leave the Mutex/Semaphore locked.

Try this example: 

Mutex new inspect critical: [1/0]

do-it, a debugger opens, step into a few times until you stand right before #primitiveExitCriticalSection, hit Abandon - and watch the owner of the Mutex

The Mutex will remain *locked* by a terminated process.

The reason is #releaseCriticalSection: assumes #terminate will finish unwinding the innermost unwind context regardless whether it has already started or not yet - i.e. #releaseCriticalSection: expects #teminate to release the Mutex or signal the Semaphore.

Unfortunately this is a general scenario: such behavior will happen whenever you Abandon a debugger inside an ensure argument block.

So back to the MNU problem; we may need the classic terminate to try to correctly release critical sections and then the MNU 'infinite recursion' fix needs to be present;

or, maybe just restrict Eliot's fix to only kick in for MNU errors inside ensure argument blocks... I haven't thought this through yet though :) 

Just FYI, the above scenario inspired this test (in the Inbox):

testMutexInCriticalEnsureArgument "self run: #testMutexInCriticalEnsureArgument"
	"This tests whether a process that is in the ensure argument block in critical: but has yet to evaluate the primitiveExitCriticalSection
	leaves it with the mutex unlocked."
	| terminatee mutex |
	mutex := Mutex new.
	terminatee := [mutex critical: []] newProcess.
	self assert: terminatee isSuspended.
	terminatee runUntil: [:ctx | ctx selectorToSendOrSelf = #primitiveExitCriticalSection].
	self assert: terminatee isSuspended.
	terminatee terminate.
	self deny: mutex isOwned.
	self assert: mutex isEmpty

Thanks for any comments,

^[^    Jaromir

Sent from Squeak Inbox Talk

On 2022-01-10T12:29:26+00:00, christoph.thiede at student.hpi.uni-potsdam.de wrote:

> Hi all, hi Eliot, hi Jaromir,
> in the last time, I observed a number of "Error: infinite recursion in doesNotUnderstand:" messages when proceeding from a DNU in the debugger. Would it be possible to disarm this again? I admit that I have not yet followed up the full background on this change, but ...:
> My usual workflow looks like this: Observe a DNU, create a new message in order to *probably* fix the issue, and press Proceed to give it a second try. If my fix was incorrect, observe a second DNU, approach a second fix, and proceed again for a third try, etc. With the recent changes to #doesNotUnderstand:, I have only got one chance to make the right fix, i.e., implement the missing method on the right class in the first attempt. If I just evaluate "nil foo" and press Proceed two consecutive times, I get this "infinite recursion" error and my iterative development cycle is broken. :-( Can we fix this?
> Long-term note: Sometime after the release(tm) I would like to revise the debugger's buttons to handle exceptions anyway, e.g., we could integrate a "retry" button for DNUs. But until then, I would really appreciate it if we could keep the existing workflows intact. Anyway, IMHO proceeding from a non-resumable exception should either) retry the operation recursively or) ignore the exception and resume right after it. At the moment, I have the feeling that we have reached neither of these directions for #doesNotUnderstand:. See also the analogous behavior in Object >> #at:. :-)
> Thanks in advance!
> Best,
> Christoph
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220110/58ec15da/attachment.html>

More information about the Squeak-dev mailing list