Re: [squeak-smalltalk/squeak-object-memory] Proceed button disabled in pre-debuggers invoked from lower-priority processes (Issue #92)

Christoph Thiede via Squeak-dev <[email protected]> Mon, 06 Jul 2026 13:09:07 -0700
Newsgroups gmane.comp.lang.smalltalk.squeak.general
Message-ID <squeak-smalltalk/squeak-object-memory/issues/92/[email protected]>
LinqLover left a comment (squeak-smalltalk/squeak-object-memory#92)

Hi Marcel, all,

since reporting this issue, I have experienced this again and again in different images and different people's machines. I think this UI glitch is worth being fixed. The workaround - first expand the debugger, then press proceed - is not intuitive and perhaps indiscoverable for non-experts.

The following hack seems to make the debug button work again without sacrificing rendering/layouting checks inside recursive error detection:

```diff
Debugger>>openWithLabel: labelString contents: contentsStringOrNil fullView: full
	"Open the receiver in a window. Note that we cannot rely on the default #buildWith: callback because debuggers can be compact (i.e. the notifier) or full, which we must decide here."
	
	| window |
	window := self
		buildWithLabel: labelString
		contents: contentsStringOrNil
		fullView: full.
	Project current
		addDeferredUIMessage: [
			"Make sure to refresh GUI elements that depend on certain process state."
-			self changed: #interruptedProcessShouldResume.
-			self changed: #interruptedProcessIsReady];
+			| block |
+			block := nil.
+			block := [interruptedProcess isSuspended
+				ifFalse: [(block future: 1) value]
+				ifTrue: [
+					self changed: #interruptedProcessShouldResume.
+					self changed: #interruptedProcessIsReady]].
+			block value];
		debugProcess: interruptedProcess "may not yet be suspended"
		inWindow: window.
	
	"Answer the receiver, but only if active process is not the process-to-debug. So in tests, use a helper process if you want to access the debugger itself."
	"self assert: [Processor activeProcess ~~ interruptedProcess]. -- works only if not simulated"
```

Attached is a less ugly patch that avoids the causing race condition instead: [wakeUpDebugger.1.cs.gz](https://github.com/user-attachments/files/29718124/wakeUpDebugger.1.cs.gz)

```diff
Debugger>>openWithLabel:contents:fullView: {initialize-release} · ct 7/6/2026 22:03 (changed)
openWithLabel: labelString contents: contentsStringOrNil fullView: full
	"Open the receiver in a window. Note that we cannot rely on the default #buildWith: callback because debuggers can be compact (i.e. the notifier) or full, which we must decide here."
	
	| window |
	window := self
		buildWithLabel: labelString
		contents: contentsStringOrNil
		fullView: full.
	Project current
- 		addDeferredUIMessage: [
- 			"Make sure to refresh GUI elements that depend on certain process state."
- 			self changed: #interruptedProcessShouldResume.
- 			self changed: #interruptedProcessIsReady];
		debugProcess: interruptedProcess "may not yet be suspended"
		inWindow: window.
	
	"Answer the receiver, but only if active process is not the process-to-debug. So in tests, use a helper process if you want to access the debugger itself."
	"self assert: [Processor activeProcess ~~ interruptedProcess]. -- works only if not simulated"

Debugger>>wakeUpDebugger {self-updating} · ct 7/6/2026 22:03
+ wakeUpDebugger
+ 	"Make sure to refresh GUI elements that depend on certain process state."
+ 	
+ 	self changed: #interruptedProcessShouldResume.
+ 	self changed: #interruptedProcessIsReady.

MVCProject>>openDebuggerWindow: {scheduling & debugging} · ct 7/6/2026 22:02 (changed)
openDebuggerWindow: windowOrModel
	"Open the window in a way that allows for the current controller to remain active."

	| window |
	window := (windowOrModel isKindOf: View)
		ifTrue: [windowOrModel]
		ifFalse: [self uiManager toolBuilder build: windowOrModel].
	
	"We might have two UI processes after #openNoTerminate if we are currently in the UI process."
	window controller openNoTerminate.

	"Try redrawing the UI at least once to avoid freeze ."
- 	self restoreDisplay. "Not safely!"
+ 	self restoreDisplay. "Not safely!"
+ 	
+ 	^ window

MorphicProject>>openDebuggerWindow: {scheduling & debugging} · ct 7/6/2026 22:02 (changed)
openDebuggerWindow: windowOrModel
	"Open the debugger window in the world. Verify integrity of visual representation here so that recursive-error detection kicks in immediately. See #guardRecursiveError:during:."

	| window |
	"Avoid occlusion from global system progress indication."
	SystemProgressMorph uniqueInstance morphicLayerNumber: Morph defaultLayer.

	"Open debugger window."
	window := self uiManager toolBuilder open: windowOrModel.
		
	"There are way too many #fullBounds sends. Layout errors might already have happened."
	window allMorphsDo: [:m |
		(m hasProperty: #errorOnLayout)
			ifTrue: [self error: 'Layout error' translated]].
	
	"Try layouting the debugger tool at least once to avoid freeze."
	self world doLayout. "Not safely! to trigger layout errors if any"
	
	"Try redrawing the UI at least once to avoid freeze."
- 	self world displayWorld. "Not safely! to trigger drawing errors if any"
+ 	self world displayWorld. "Not safely! to trigger drawing errors if any"
+ 	
+ 	^ window

Project>>debugProcess:inWindow: {scheduling & debugging} · ct 7/6/2026 22:02 (changed)
- debugProcess: processToDebug inWindow: aViewOrModel
+ debugProcess: processToDebug inWindow: aViewOrModel 
	"Safely open a 'debugger tool' (here: aViewOrModel) on processToDebug. Projects can customize prepare-open-suspend hooks to keep the UI (and system) responsive. Also see #resumeProcessSafely:. There should be no need to overwrite this method in subclasses but only the hooks."

- 	self
- 		prepareProcessForDebugger: processToDebug;
- 		openDebuggerWindow: aViewOrModel;
- 		suspendProcessSafely: processToDebug.
+ 	| view model |
+ 	self prepareProcessForDebugger: processToDebug.
+ 	view := self openDebuggerWindow: aViewOrModel.
+ 	model := view model.
+ 	(model respondsTo: #wakeUpDebugger) ifTrue:
+ 		[self addDeferredUIMessage: [model wakeUpDebugger]].
+ 	self suspendProcessSafely: processToDebug.

Project>>openDebuggerWindow: {scheduling & debugging} · ct 7/6/2026 22:02 (changed)
openDebuggerWindow: aViewOrModel
- 	"Build an interactive view in the current GUI framework."
+ 	"Build and answer an interactive view in the current GUI framework."

- 	self uiManager toolBuilder open: aViewOrModel.
+ 	^ self uiManager toolBuilder open: aViewOrModel
```

Looking forward to your feedback! Let's get this fixed. :-)

Best,
Christoph

-- 
Reply to this email directly or view it on GitHub:
https://github.com/squeak-smalltalk/squeak-object-memory/issues/92#issuecomment-4897164278
You are receiving this because you are subscribed to this thread.

Message ID: <squeak-smalltalk/squeak-object-memory/issues/92/[email protected]>

Squeak-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]