[BUG][FIX][2.8] Debugger can't debug non-UI threads

Bob Arning arning at charm.net
Mon Jul 31 03:54:03 UTC 2000


Hi Ned,

This sounded so familiar! I dug up some code from last December that I failed to lobby hard enough for. I have adjusted it for 2.8 and attached it below. Please try it out and see if you have any problems. I will see that it gets in the updates this time.

Notes:
-- 2.8 ONLY! - I will make one for 2.9 once this gets settled
-- This fixes the problem in Morphic and I don't think it harms MVC.

Cheers,
Bob

On Sun, 30 Jul 2000 13:58:56 -0700 Ned Konz <ned at bike-nomad.com> wrote:
>When it resumes, it makes the interrupted process the current UI process.
>
>To demonstrate this, evaluate the following in a Workspace (it's more obvious
>in Morphic, as the MVC debugger doesn't appear immediately):
>
>	[ self halt ] fork
>
>Now try to proceed, or debug and then resume.
>
>The UI locks up.
>
>Any suggestions?
>
>Perhaps the Debugger can have a flag that tells it whether the interrupted
>process was indeed the UI process, and it could resume accordingly.

===== code follows =====
'From Squeak2.8 of 13 June 2000 [latest update: #2347] on 30 July 2000 at 11:19:35 pm'!
"Change Set:		debugFix3
Date:			30 July 2000
Author:			Bob Arning

When a non-ui process encounters an error, the debugger does not need to create a new ui process. It was however terminating the active process on resuming from the (non-ui) error. This left no ui process running. The change here is to leave the ui process running in such cases"!

CodeHolder subclass: #Debugger
	instanceVariableNames: 'interruptedProcess interruptedController contextStack contextStackTop contextStackIndex contextStackList receiverInspector contextVariablesInspector externalInterrupt proceedValue selectingPC sourceMap tempNames savedCursor isolationHead failedProject errorWasInUIProcess '
	classVariableNames: 'ContextStackKeystrokes ErrorRecursion '
	poolDictionaries: ''
	category: 'Tools-Debugger'!

!Debugger methodsFor: 'initialize' stamp: 'RAA 7/30/2000 23:04'!
openFullNoSuspendLabel: aString
	"Create and schedule a full debugger with the given label. Do not terminate the current active process."

	| topView |
	Smalltalk isMorphic ifTrue: [
		self openFullMorphicLabel: aString.
		errorWasInUIProcess _ Project current spawnNewProcessIfThisIsUI: interruptedProcess.
		^self
	].
	topView _ self buildMVCDebuggerViewLabel: aString minSize: 300 at 200.
	topView controller openNoTerminate.
	^ topView
! !

!Debugger methodsFor: 'initialize' stamp: 'RAA 7/30/2000 23:05'!
openNotifierContents: msgString label: label
	"Create and schedule a notifier view with the given label and message. A notifier view shows just the message or the first several lines of the stack, with a menu that allows the user to open a full debugger if so desired."
	"NOTE: When this method returns, a new process has been scheduled to run the windows, and thus this notifier, but the previous active porcess has not been suspended.  The sender will do this."
	| msg topView p |
	Sensor flushKeyboard.
	savedCursor _ Sensor currentCursor.
	Sensor currentCursor: Cursor normal.
	msg _ msgString.
	(label beginsWith: 'Space is low') ifTrue: [msg _ self lowSpaceChoices, msgString].
	isolationHead ifNotNil:
		["We have already revoked the isolation layer -- now jump to the parent project."
		msg _ self isolationRecoveryAdvice, msgString.
		failedProject _ Project current.
		isolationHead parent enterForEmergencyRecovery].

	Smalltalk isMorphic ifTrue: [
		self buildMorphicNotifierLabelled: label message: msg.
		errorWasInUIProcess _ Project current spawnNewProcessIfThisIsUI: interruptedProcess.
		^self
	].

	Display fullScreen.
	topView _ self buildMVCNotifierViewLabel: label message: msg minSize: 350@((14 * 5) + 16 + self optionalButtonHeight).
	ScheduledControllers activeController
		ifNil: [p _ Display boundingBox center]
		ifNotNil: [p _ ScheduledControllers activeController view displayBox center].
	topView controller openNoTerminateDisplayAt: (p max: (200 at 60)).
	^ topView! !

!Debugger methodsFor: 'private' stamp: 'RAA 7/30/2000 23:19'!
resumeProcess: aTopView 
	Smalltalk isMorphic ifFalse: [aTopView erase].
	savedCursor ifNotNil: [Sensor currentCursor: savedCursor].
	isolationHead
		ifNotNil: 
			[failedProject enterForEmergencyRecovery.
			isolationHead invoke.
			isolationHead _ nil].
	interruptedProcess suspendedContext method == (Process compiledMethodAt: #terminate)
		ifFalse: 
			[contextStackIndex > 1
				ifTrue: [interruptedProcess popTo: self selectedContext]
				ifFalse: [interruptedProcess install: self selectedContext].
			Smalltalk isMorphic
				ifTrue: [errorWasInUIProcess
						ifTrue: [Project current resumeProcess: interruptedProcess]
						ifFalse: [interruptedProcess resume]]
				ifFalse: [ScheduledControllers activeControllerNoTerminate: interruptedController andProcess: interruptedProcess]].
	"if old process was terminated, just terminate current one"
	interruptedProcess _ nil.
	"Before delete, so release doesn't terminate it"
	Smalltalk isMorphic
		ifTrue: 
			[aTopView delete.
			World displayWorld]
		ifFalse: [aTopView controller closeAndUnscheduleNoErase].
	Smalltalk installLowSpaceWatcher.
	"restart low space handler"
	errorWasInUIProcess == false ifFalse: [Processor terminateActive]! !


!Project methodsFor: 'active process' stamp: 'RAA 7/30/2000 22:56'!
spawnNewProcessIfThisIsUI: suspendedProcess

	world isMorph ifFalse: [	"does this ever happen?"
		self spawnNewProcess.
		^true
	].
	self activeProcess == suspendedProcess ifTrue: [
		self spawnNewProcess.
		^true
	].
	^false		"no new process was created"! !






More information about the Squeak-dev mailing list