The Trunk: Morphic-mt.1540.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Morphic-mt.1540.mcz

commits-2
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1540.mcz

==================== Summary ====================

Name: Morphic-mt.1540
Author: mt
Time: 24 September 2019, 5:18:23.87286 pm
UUID: a049a4c1-b81f-3b4e-8aa3-cb0ecad08561
Ancestors: Morphic-mt.1539

Complements Tools-mt.893:
- more comments
- some additional warnings for usability

=============== Diff against Morphic-mt.1539 ===============

Item was changed:
  ----- Method: MorphicDebugger class>>openDrawingErrors: (in category 'opening') -----
  openDrawingErrors: errors
+ "Open debuggers for all different errors found. DO NOT suspend the active process because drawing errors got caught gracefully already to keep the system running. The debuggers are only for exploration."
- "Open debuggers for all different errors found."
 
  self setErrorRecursion.
  errors do: [:processToLabel |
+ (self new process: processToLabel key context: processToLabel key suspendedContext)
+ errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
+ openNotifierNoSuspendContents: nil label: processToLabel value].
- (MorphicDebugger new process: processToLabel key context: processToLabel key suspendedContext)
- errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
- openNotifierContents: nil label: processToLabel value].
 
  "Try to draw the debuggers or else there will be no chance to escape from this catch-drawing-error loop."
  Project current world displayWorld.
  self clearErrorRecursion.!

Item was changed:
  ----- Method: MorphicDebugger class>>openInterrupt:onProcess: (in category 'opening') -----
  openInterrupt: aString onProcess: interruptedProcess
  "Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."
 
+ | errorWasInUIProcess debugger message |
- | errorWasInUIProcess debugger |
  <primitive: 19> "Simulation guard"
 
+ Processor activeProcess == Project current uiProcess
+ ifTrue: [^ self notify: 'You cannot interrupt from within the UI process. Use a helper process instead.\\This interrupt request will be aborted.' withCRs translated].
+
  errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: interruptedProcess.
+
  debugger := self new.
  debugger
  process: interruptedProcess
  context: interruptedProcess suspendedContext.
  debugger
  externalInterrupt: true;
  errorWasInUIProcess: errorWasInUIProcess.
 
+ ((aString includesSubstring: 'Space') and: [aString includesSubstring: 'low'])
+ ifTrue: [
+ "Space is low!! See SmalltalkImage >> #lowSpaceWatcher."
+ message := self lowSpaceChoices.
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']]
+ ifFalse: [
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logSqueakError: aString inContext: debugger interruptedContext]].
- Preferences logDebuggerStackToFile ifTrue:
- [(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
- ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
- "logging disabled for 4.3 release, see
- http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
- "ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].
 
+ ^ debugger
+ openNotifierNoSuspendContents: message label: aString;
- Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
- ^debugger
- openNotifierContents: nil label: aString;
  yourself
  !

Item was changed:
  ----- Method: MorphicDebugger class>>openOn:context:label:contents:fullView: (in category 'opening') -----
  openOn: process context: context label: title contents: contentsStringOrNil fullView: full
  "Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."
 
  ErrorRecursionGuard critical: [
 
  | errorWasInUIProcess debugger |
  ErrorRecursion ifTrue: [
  "self assert: process == Project current uiProcess -- DOCUMENTATION ONLY"
  self clearErrorRecursion.
  ^ Project current handleFatalDrawingError: title].
 
  [ErrorRecursion not & Preferences logDebuggerStackToFile
  ifTrue: [Smalltalk logSqueakError: title inContext: context]]
  on: Error
  do: [:ex | ex return: nil].
 
  errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: process.
 
  "Schedule debugging in deferred UI message because
  1) If process is the current UI process, it is already broken.
  2) If process is some other process, it must not execute UI code"
  Project current addDeferredUIMessage: [
+ ErrorRecursionGuard critical: [
+ self setErrorRecursion.
+
+ self informExistingDebugger: context label: title.
+
+ debugger := self new process: process context: context.
+ full
+ ifTrue: [debugger openFullNoSuspendLabel: title]
+ ifFalse: [debugger openNotifierNoSuspendContents: contentsStringOrNil label: title].
+ debugger errorWasInUIProcess: errorWasInUIProcess.
- self setErrorRecursion.
 
+ "Try drawing the debugger tool at least once to avoid freeze."
+ Project current world displayWorldSafely.
+
+ self clearErrorRecursion] ]].
- self informExistingDebugger: context label: title.
-
- debugger := self new process: process context: context.
- full
- ifTrue: [debugger openFullNoSuspendLabel: title]
- ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
- debugger errorWasInUIProcess: errorWasInUIProcess.
-
- "Try drawing the debugger tool at least once to avoid freeze."
- Project current world displayWorldSafely.
-
- self clearErrorRecursion]].
 
  process suspend.!

Item was changed:
  ----- Method: MorphicDebugger class>>openOnMethod:forReceiver:inContext: (in category 'opening') -----
  openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil
 
+ | guineaPig debugger context |
- | guineaPig debugger debuggerWindow context |
  guineaPig :=
  [aCompiledMethod
  valueWithReceiver: anObject
  arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
  guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
  context := guineaPig suspendedContext.
+
  debugger := self new
  process: guineaPig
  context: context.
+ debugger initializeFull.
+
- debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
  "Now step into the expression.  But if it is quick (is implemented as a primtiive, e.g. `0')
  it will return immediately back to the block that is sent newProcess above.  Guard
  against that with the check for home being thisContext."
  [debugger interruptedContext method == aCompiledMethod]
+ whileFalse: [
+ (guineaPig isNil and: [debugger interruptedContext home == thisContext])
+ ifTrue: [^ Project uiManager inform: 'Nothing to debug; expression is optimized'].
+ debugger send].
+
+ debugger openFullNoSuspendLabel: 'Debug it'.!
- whileFalse:
- [(guineaPig isNil
-  and: [debugger interruptedContext home == thisContext]) ifTrue:
- [debuggerWindow delete.
- UIManager default inform: 'Nothing to debug; expression is optimized'.
- ^self].
- debugger send]!

Item was added:
+ ----- Method: MorphicDebugger>>abandon: (in category 'initialize') -----
+ abandon: myWindow
+
+ myWindow delete.!

Item was added:
+ ----- Method: MorphicDebugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: notifierWindow
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullFromNotifier: notifierWindow.
+
+ notifierWindow delete.
+
+ ^ ToolBuilder default
+ open: self
+ label: notifierWindow label!

Item was added:
+ ----- Method: MorphicDebugger>>openFullNoSuspendLabel: (in category 'initialize') -----
+ openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullNoSuspendLabel: aString.
+
+ ^ ToolBuilder default
+ open: self
+ label: aString!

Item was added:
+ ----- Method: MorphicDebugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+
+ | builder spec |
+ super openNotifierNoSuspendContents: msgString label: label.
+
+ builder := ToolBuilder default.
+ spec := self buildNotifierWith: builder label: label message: msgString.
+
+ ^ ToolBuilder default open: spec!

Item was added:
+ ----- Method: MorphicProject>>interruptCleanUpFor: (in category 'scheduling & debugging') -----
+ interruptCleanUpFor: interruptedProcess
+ "Clean up things in case of a process interrupt."
+
+ super interruptCleanUpFor: interruptedProcess.
+
+ (Preferences eToyFriendly and: [interruptedProcess == self uiProcess])
+ ifTrue: [Project current world stopRunningAll].!

Item was changed:
  ----- Method: MorphicProject>>interruptName:preemptedProcess: (in category 'scheduling & debugging') -----
  interruptName: labelString preemptedProcess: theInterruptedProcess
  "Create a Notifier on the active scheduling process with the given label."
 
  | preemptedProcess projectProcess |
+ self uiProcess == Processor activeProcess ifTrue: [
+ ^ self inform: 'You cannot interrupt from within the UI process.\Use a helper process instead.' withCRs translated].
+
  ActiveHand ifNotNil:[ActiveHand interrupted].
  ActiveWorld := world. "reinstall active globals"
  ActiveHand := world primaryHand.
  ActiveHand interrupted. "make sure this one's interrupted too"
  ActiveEvent := nil.
 
  projectProcess := self uiProcess. "we still need the accessor for a while"
  preemptedProcess := theInterruptedProcess ifNil: [Processor preemptedProcess].
  "Only debug preempted process if its priority is >= projectProcess' priority"
  preemptedProcess priority < projectProcess priority
  ifTrue:[preemptedProcess := projectProcess].
+
  preemptedProcess suspend.
+ self interruptCleanUpFor: preemptedProcess.
 
  ToolSet
  debugInterruptedProcess: preemptedProcess
  label: labelString.!

Item was added:
+ ----- Method: MorphicProject>>startUpActions (in category 'enter') -----
+ startUpActions
+
+ super startUpActions.
+
+ self world install.
+ self world firstHand position: 100@100.!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1540.mcz

marcel.taeumel
I forgot to mention that I added the ErrorRecursionGuard to the deferred UI message, too, to make it more effective for error-throwing non-ui processes. :-)

Best,
Marcel

Am 24.09.2019 17:18:45 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1540.mcz

==================== Summary ====================

Name: Morphic-mt.1540
Author: mt
Time: 24 September 2019, 5:18:23.87286 pm
UUID: a049a4c1-b81f-3b4e-8aa3-cb0ecad08561
Ancestors: Morphic-mt.1539

Complements Tools-mt.893:
- more comments
- some additional warnings for usability

=============== Diff against Morphic-mt.1539 ===============

Item was changed:
----- Method: MorphicDebugger class>>openDrawingErrors: (in category 'opening') -----
openDrawingErrors: errors
+ "Open debuggers for all different errors found. DO NOT suspend the active process because drawing errors got caught gracefully already to keep the system running. The debuggers are only for exploration."
- "Open debuggers for all different errors found."

self setErrorRecursion.
errors do: [:processToLabel |
+ (self new process: processToLabel key context: processToLabel key suspendedContext)
+ errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
+ openNotifierNoSuspendContents: nil label: processToLabel value].
- (MorphicDebugger new process: processToLabel key context: processToLabel key suspendedContext)
- errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
- openNotifierContents: nil label: processToLabel value].

"Try to draw the debuggers or else there will be no chance to escape from this catch-drawing-error loop."
Project current world displayWorld.
self clearErrorRecursion.!

Item was changed:
----- Method: MorphicDebugger class>>openInterrupt:onProcess: (in category 'opening') -----
openInterrupt: aString onProcess: interruptedProcess
"Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."

+ | errorWasInUIProcess debugger message |
- | errorWasInUIProcess debugger |
"Simulation guard"

+ Processor activeProcess == Project current uiProcess
+ ifTrue: [^ self notify: 'You cannot interrupt from within the UI process. Use a helper process instead.\\This interrupt request will be aborted.' withCRs translated].
+
errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: interruptedProcess.
+
debugger := self new.
debugger
process: interruptedProcess
context: interruptedProcess suspendedContext.
debugger
externalInterrupt: true;
errorWasInUIProcess: errorWasInUIProcess.

+ ((aString includesSubstring: 'Space') and: [aString includesSubstring: 'low'])
+ ifTrue: [
+ "Space is low!! See SmalltalkImage >> #lowSpaceWatcher."
+ message := self lowSpaceChoices.
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']]
+ ifFalse: [
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logSqueakError: aString inContext: debugger interruptedContext]].
- Preferences logDebuggerStackToFile ifTrue:
- [(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
- ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
- "logging disabled for 4.3 release, see
- http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
- "ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].

+ ^ debugger
+ openNotifierNoSuspendContents: message label: aString;
- Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
- ^debugger
- openNotifierContents: nil label: aString;
yourself
!

Item was changed:
----- Method: MorphicDebugger class>>openOn:context:label:contents:fullView: (in category 'opening') -----
openOn: process context: context label: title contents: contentsStringOrNil fullView: full
"Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."

ErrorRecursionGuard critical: [

| errorWasInUIProcess debugger |
ErrorRecursion ifTrue: [
"self assert: process == Project current uiProcess -- DOCUMENTATION ONLY"
self clearErrorRecursion.
^ Project current handleFatalDrawingError: title].

[ErrorRecursion not & Preferences logDebuggerStackToFile
ifTrue: [Smalltalk logSqueakError: title inContext: context]]
on: Error
do: [:ex | ex return: nil].

errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: process.

"Schedule debugging in deferred UI message because
1) If process is the current UI process, it is already broken.
2) If process is some other process, it must not execute UI code"
Project current addDeferredUIMessage: [
+ ErrorRecursionGuard critical: [
+ self setErrorRecursion.
+
+ self informExistingDebugger: context label: title.
+
+ debugger := self new process: process context: context.
+ full
+ ifTrue: [debugger openFullNoSuspendLabel: title]
+ ifFalse: [debugger openNotifierNoSuspendContents: contentsStringOrNil label: title].
+ debugger errorWasInUIProcess: errorWasInUIProcess.
- self setErrorRecursion.

+ "Try drawing the debugger tool at least once to avoid freeze."
+ Project current world displayWorldSafely.
+
+ self clearErrorRecursion] ]].
- self informExistingDebugger: context label: title.
-
- debugger := self new process: process context: context.
- full
- ifTrue: [debugger openFullNoSuspendLabel: title]
- ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
- debugger errorWasInUIProcess: errorWasInUIProcess.
-
- "Try drawing the debugger tool at least once to avoid freeze."
- Project current world displayWorldSafely.
-
- self clearErrorRecursion]].

process suspend.!

Item was changed:
----- Method: MorphicDebugger class>>openOnMethod:forReceiver:inContext: (in category 'opening') -----
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

+ | guineaPig debugger context |
- | guineaPig debugger debuggerWindow context |
guineaPig :=
[aCompiledMethod
valueWithReceiver: anObject
arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
context := guineaPig suspendedContext.
+
debugger := self new
process: guineaPig
context: context.
+ debugger initializeFull.
+
- debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
"Now step into the expression. But if it is quick (is implemented as a primtiive, e.g. `0')
it will return immediately back to the block that is sent newProcess above. Guard
against that with the check for home being thisContext."
[debugger interruptedContext method == aCompiledMethod]
+ whileFalse: [
+ (guineaPig isNil and: [debugger interruptedContext home == thisContext])
+ ifTrue: [^ Project uiManager inform: 'Nothing to debug; expression is optimized'].
+ debugger send].
+
+ debugger openFullNoSuspendLabel: 'Debug it'.!
- whileFalse:
- [(guineaPig isNil
- and: [debugger interruptedContext home == thisContext]) ifTrue:
- [debuggerWindow delete.
- UIManager default inform: 'Nothing to debug; expression is optimized'.
- ^self].
- debugger send]!

Item was added:
+ ----- Method: MorphicDebugger>>abandon: (in category 'initialize') -----
+ abandon: myWindow
+
+ myWindow delete.!

Item was added:
+ ----- Method: MorphicDebugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: notifierWindow
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullFromNotifier: notifierWindow.
+
+ notifierWindow delete.
+
+ ^ ToolBuilder default
+ open: self
+ label: notifierWindow label!

Item was added:
+ ----- Method: MorphicDebugger>>openFullNoSuspendLabel: (in category 'initialize') -----
+ openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullNoSuspendLabel: aString.
+
+ ^ ToolBuilder default
+ open: self
+ label: aString!

Item was added:
+ ----- Method: MorphicDebugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+
+ | builder spec |
+ super openNotifierNoSuspendContents: msgString label: label.
+
+ builder := ToolBuilder default.
+ spec := self buildNotifierWith: builder label: label message: msgString.
+
+ ^ ToolBuilder default open: spec!

Item was added:
+ ----- Method: MorphicProject>>interruptCleanUpFor: (in category 'scheduling & debugging') -----
+ interruptCleanUpFor: interruptedProcess
+ "Clean up things in case of a process interrupt."
+
+ super interruptCleanUpFor: interruptedProcess.
+
+ (Preferences eToyFriendly and: [interruptedProcess == self uiProcess])
+ ifTrue: [Project current world stopRunningAll].!

Item was changed:
----- Method: MorphicProject>>interruptName:preemptedProcess: (in category 'scheduling & debugging') -----
interruptName: labelString preemptedProcess: theInterruptedProcess
"Create a Notifier on the active scheduling process with the given label."

| preemptedProcess projectProcess |
+ self uiProcess == Processor activeProcess ifTrue: [
+ ^ self inform: 'You cannot interrupt from within the UI process.\Use a helper process instead.' withCRs translated].
+
ActiveHand ifNotNil:[ActiveHand interrupted].
ActiveWorld := world. "reinstall active globals"
ActiveHand := world primaryHand.
ActiveHand interrupted. "make sure this one's interrupted too"
ActiveEvent := nil.

projectProcess := self uiProcess. "we still need the accessor for a while"
preemptedProcess := theInterruptedProcess ifNil: [Processor preemptedProcess].
"Only debug preempted process if its priority is >= projectProcess' priority"
preemptedProcess priority < projectprocess="" priority="">
ifTrue:[preemptedProcess := projectProcess].
+
preemptedProcess suspend.
+ self interruptCleanUpFor: preemptedProcess.

ToolSet
debugInterruptedProcess: preemptedProcess
label: labelString.!

Item was added:
+ ----- Method: MorphicProject>>startUpActions (in category 'enter') -----
+ startUpActions
+
+ super startUpActions.
+
+ self world install.
+ self world firstHand position: 100@100.!




Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1540.mcz

Nicolas Cellier
Hi Marcel,
it seems like there's a new failing test with this one...
DebuggerUnwindBug >> #testUnwindDebugger

Le mar. 24 sept. 2019 à 17:28, Marcel Taeumel <[hidden email]> a écrit :
I forgot to mention that I added the ErrorRecursionGuard to the deferred UI message, too, to make it more effective for error-throwing non-ui processes. :-)

Best,
Marcel

Am 24.09.2019 17:18:45 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1540.mcz

==================== Summary ====================

Name: Morphic-mt.1540
Author: mt
Time: 24 September 2019, 5:18:23.87286 pm
UUID: a049a4c1-b81f-3b4e-8aa3-cb0ecad08561
Ancestors: Morphic-mt.1539

Complements Tools-mt.893:
- more comments
- some additional warnings for usability

=============== Diff against Morphic-mt.1539 ===============

Item was changed:
----- Method: MorphicDebugger class>>openDrawingErrors: (in category 'opening') -----
openDrawingErrors: errors
+ "Open debuggers for all different errors found. DO NOT suspend the active process because drawing errors got caught gracefully already to keep the system running. The debuggers are only for exploration."
- "Open debuggers for all different errors found."

self setErrorRecursion.
errors do: [:processToLabel |
+ (self new process: processToLabel key context: processToLabel key suspendedContext)
+ errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
+ openNotifierNoSuspendContents: nil label: processToLabel value].
- (MorphicDebugger new process: processToLabel key context: processToLabel key suspendedContext)
- errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
- openNotifierContents: nil label: processToLabel value].

"Try to draw the debuggers or else there will be no chance to escape from this catch-drawing-error loop."
Project current world displayWorld.
self clearErrorRecursion.!

Item was changed:
----- Method: MorphicDebugger class>>openInterrupt:onProcess: (in category 'opening') -----
openInterrupt: aString onProcess: interruptedProcess
"Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."

+ | errorWasInUIProcess debugger message |
- | errorWasInUIProcess debugger |
"Simulation guard"

+ Processor activeProcess == Project current uiProcess
+ ifTrue: [^ self notify: 'You cannot interrupt from within the UI process. Use a helper process instead.\\This interrupt request will be aborted.' withCRs translated].
+
errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: interruptedProcess.
+
debugger := self new.
debugger
process: interruptedProcess
context: interruptedProcess suspendedContext.
debugger
externalInterrupt: true;
errorWasInUIProcess: errorWasInUIProcess.

+ ((aString includesSubstring: 'Space') and: [aString includesSubstring: 'low'])
+ ifTrue: [
+ "Space is low!! See SmalltalkImage >> #lowSpaceWatcher."
+ message := self lowSpaceChoices.
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']]
+ ifFalse: [
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logSqueakError: aString inContext: debugger interruptedContext]].
- Preferences logDebuggerStackToFile ifTrue:
- [(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
- ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
- "logging disabled for 4.3 release, see
- http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
- "ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].

+ ^ debugger
+ openNotifierNoSuspendContents: message label: aString;
- Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
- ^debugger
- openNotifierContents: nil label: aString;
yourself
!

Item was changed:
----- Method: MorphicDebugger class>>openOn:context:label:contents:fullView: (in category 'opening') -----
openOn: process context: context label: title contents: contentsStringOrNil fullView: full
"Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."

ErrorRecursionGuard critical: [

| errorWasInUIProcess debugger |
ErrorRecursion ifTrue: [
"self assert: process == Project current uiProcess -- DOCUMENTATION ONLY"
self clearErrorRecursion.
^ Project current handleFatalDrawingError: title].

[ErrorRecursion not & Preferences logDebuggerStackToFile
ifTrue: [Smalltalk logSqueakError: title inContext: context]]
on: Error
do: [:ex | ex return: nil].

errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: process.

"Schedule debugging in deferred UI message because
1) If process is the current UI process, it is already broken.
2) If process is some other process, it must not execute UI code"
Project current addDeferredUIMessage: [
+ ErrorRecursionGuard critical: [
+ self setErrorRecursion.
+
+ self informExistingDebugger: context label: title.
+
+ debugger := self new process: process context: context.
+ full
+ ifTrue: [debugger openFullNoSuspendLabel: title]
+ ifFalse: [debugger openNotifierNoSuspendContents: contentsStringOrNil label: title].
+ debugger errorWasInUIProcess: errorWasInUIProcess.
- self setErrorRecursion.

+ "Try drawing the debugger tool at least once to avoid freeze."
+ Project current world displayWorldSafely.
+
+ self clearErrorRecursion] ]].
- self informExistingDebugger: context label: title.
-
- debugger := self new process: process context: context.
- full
- ifTrue: [debugger openFullNoSuspendLabel: title]
- ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
- debugger errorWasInUIProcess: errorWasInUIProcess.
-
- "Try drawing the debugger tool at least once to avoid freeze."
- Project current world displayWorldSafely.
-
- self clearErrorRecursion]].

process suspend.!

Item was changed:
----- Method: MorphicDebugger class>>openOnMethod:forReceiver:inContext: (in category 'opening') -----
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

+ | guineaPig debugger context |
- | guineaPig debugger debuggerWindow context |
guineaPig :=
[aCompiledMethod
valueWithReceiver: anObject
arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
context := guineaPig suspendedContext.
+
debugger := self new
process: guineaPig
context: context.
+ debugger initializeFull.
+
- debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
"Now step into the expression. But if it is quick (is implemented as a primtiive, e.g. `0')
it will return immediately back to the block that is sent newProcess above. Guard
against that with the check for home being thisContext."
[debugger interruptedContext method == aCompiledMethod]
+ whileFalse: [
+ (guineaPig isNil and: [debugger interruptedContext home == thisContext])
+ ifTrue: [^ Project uiManager inform: 'Nothing to debug; expression is optimized'].
+ debugger send].
+
+ debugger openFullNoSuspendLabel: 'Debug it'.!
- whileFalse:
- [(guineaPig isNil
- and: [debugger interruptedContext home == thisContext]) ifTrue:
- [debuggerWindow delete.
- UIManager default inform: 'Nothing to debug; expression is optimized'.
- ^self].
- debugger send]!

Item was added:
+ ----- Method: MorphicDebugger>>abandon: (in category 'initialize') -----
+ abandon: myWindow
+
+ myWindow delete.!

Item was added:
+ ----- Method: MorphicDebugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: notifierWindow
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullFromNotifier: notifierWindow.
+
+ notifierWindow delete.
+
+ ^ ToolBuilder default
+ open: self
+ label: notifierWindow label!

Item was added:
+ ----- Method: MorphicDebugger>>openFullNoSuspendLabel: (in category 'initialize') -----
+ openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullNoSuspendLabel: aString.
+
+ ^ ToolBuilder default
+ open: self
+ label: aString!

Item was added:
+ ----- Method: MorphicDebugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+
+ | builder spec |
+ super openNotifierNoSuspendContents: msgString label: label.
+
+ builder := ToolBuilder default.
+ spec := self buildNotifierWith: builder label: label message: msgString.
+
+ ^ ToolBuilder default open: spec!

Item was added:
+ ----- Method: MorphicProject>>interruptCleanUpFor: (in category 'scheduling & debugging') -----
+ interruptCleanUpFor: interruptedProcess
+ "Clean up things in case of a process interrupt."
+
+ super interruptCleanUpFor: interruptedProcess.
+
+ (Preferences eToyFriendly and: [interruptedProcess == self uiProcess])
+ ifTrue: [Project current world stopRunningAll].!

Item was changed:
----- Method: MorphicProject>>interruptName:preemptedProcess: (in category 'scheduling & debugging') -----
interruptName: labelString preemptedProcess: theInterruptedProcess
"Create a Notifier on the active scheduling process with the given label."

| preemptedProcess projectProcess |
+ self uiProcess == Processor activeProcess ifTrue: [
+ ^ self inform: 'You cannot interrupt from within the UI process.\Use a helper process instead.' withCRs translated].
+
ActiveHand ifNotNil:[ActiveHand interrupted].
ActiveWorld := world. "reinstall active globals"
ActiveHand := world primaryHand.
ActiveHand interrupted. "make sure this one's interrupted too"
ActiveEvent := nil.

projectProcess := self uiProcess. "we still need the accessor for a while"
preemptedProcess := theInterruptedProcess ifNil: [Processor preemptedProcess].
"Only debug preempted process if its priority is >= projectProcess' priority"
preemptedProcess priority < projectprocess="" priority="">
ifTrue:[preemptedProcess := projectProcess].
+
preemptedProcess suspend.
+ self interruptCleanUpFor: preemptedProcess.

ToolSet
debugInterruptedProcess: preemptedProcess
label: labelString.!

Item was added:
+ ----- Method: MorphicProject>>startUpActions (in category 'enter') -----
+ startUpActions
+
+ super startUpActions.
+
+ self world install.
+ self world firstHand position: 100@100.!





Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1540.mcz

marcel.taeumel
Yup, I am on it. Almost finished. I will further simplify the interface between Debugger, ToolSet and Project.

Best,
Marcel

Am 30.09.2019 23:00:02 schrieb Nicolas Cellier <[hidden email]>:

Hi Marcel,
it seems like there's a new failing test with this one...
DebuggerUnwindBug >> #testUnwindDebugger

Le mar. 24 sept. 2019 à 17:28, Marcel Taeumel <[hidden email]> a écrit :
I forgot to mention that I added the ErrorRecursionGuard to the deferred UI message, too, to make it more effective for error-throwing non-ui processes. :-)

Best,
Marcel

Am 24.09.2019 17:18:45 schrieb [hidden email] <[hidden email]>:

Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1540.mcz

==================== Summary ====================

Name: Morphic-mt.1540
Author: mt
Time: 24 September 2019, 5:18:23.87286 pm
UUID: a049a4c1-b81f-3b4e-8aa3-cb0ecad08561
Ancestors: Morphic-mt.1539

Complements Tools-mt.893:
- more comments
- some additional warnings for usability

=============== Diff against Morphic-mt.1539 ===============

Item was changed:
----- Method: MorphicDebugger class>>openDrawingErrors: (in category 'opening') -----
openDrawingErrors: errors
+ "Open debuggers for all different errors found. DO NOT suspend the active process because drawing errors got caught gracefully already to keep the system running. The debuggers are only for exploration."
- "Open debuggers for all different errors found."

self setErrorRecursion.
errors do: [:processToLabel |
+ (self new process: processToLabel key context: processToLabel key suspendedContext)
+ errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
+ openNotifierNoSuspendContents: nil label: processToLabel value].
- (MorphicDebugger new process: processToLabel key context: processToLabel key suspendedContext)
- errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
- openNotifierContents: nil label: processToLabel value].

"Try to draw the debuggers or else there will be no chance to escape from this catch-drawing-error loop."
Project current world displayWorld.
self clearErrorRecursion.!

Item was changed:
----- Method: MorphicDebugger class>>openInterrupt:onProcess: (in category 'opening') -----
openInterrupt: aString onProcess: interruptedProcess
"Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."

+ | errorWasInUIProcess debugger message |
- | errorWasInUIProcess debugger |
"Simulation guard"

+ Processor activeProcess == Project current uiProcess
+ ifTrue: [^ self notify: 'You cannot interrupt from within the UI process. Use a helper process instead.\\This interrupt request will be aborted.' withCRs translated].
+
errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: interruptedProcess.
+
debugger := self new.
debugger
process: interruptedProcess
context: interruptedProcess suspendedContext.
debugger
externalInterrupt: true;
errorWasInUIProcess: errorWasInUIProcess.

+ ((aString includesSubstring: 'Space') and: [aString includesSubstring: 'low'])
+ ifTrue: [
+ "Space is low!! See SmalltalkImage >> #lowSpaceWatcher."
+ message := self lowSpaceChoices.
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']]
+ ifFalse: [
+ Preferences logDebuggerStackToFile ifTrue: [
+ Smalltalk logSqueakError: aString inContext: debugger interruptedContext]].
- Preferences logDebuggerStackToFile ifTrue:
- [(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
- ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
- "logging disabled for 4.3 release, see
- http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
- "ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].

+ ^ debugger
+ openNotifierNoSuspendContents: message label: aString;
- Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
- ^debugger
- openNotifierContents: nil label: aString;
yourself
!

Item was changed:
----- Method: MorphicDebugger class>>openOn:context:label:contents:fullView: (in category 'opening') -----
openOn: process context: context label: title contents: contentsStringOrNil fullView: full
"Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."

ErrorRecursionGuard critical: [

| errorWasInUIProcess debugger |
ErrorRecursion ifTrue: [
"self assert: process == Project current uiProcess -- DOCUMENTATION ONLY"
self clearErrorRecursion.
^ Project current handleFatalDrawingError: title].

[ErrorRecursion not & Preferences logDebuggerStackToFile
ifTrue: [Smalltalk logSqueakError: title inContext: context]]
on: Error
do: [:ex | ex return: nil].

errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: process.

"Schedule debugging in deferred UI message because
1) If process is the current UI process, it is already broken.
2) If process is some other process, it must not execute UI code"
Project current addDeferredUIMessage: [
+ ErrorRecursionGuard critical: [
+ self setErrorRecursion.
+
+ self informExistingDebugger: context label: title.
+
+ debugger := self new process: process context: context.
+ full
+ ifTrue: [debugger openFullNoSuspendLabel: title]
+ ifFalse: [debugger openNotifierNoSuspendContents: contentsStringOrNil label: title].
+ debugger errorWasInUIProcess: errorWasInUIProcess.
- self setErrorRecursion.

+ "Try drawing the debugger tool at least once to avoid freeze."
+ Project current world displayWorldSafely.
+
+ self clearErrorRecursion] ]].
- self informExistingDebugger: context label: title.
-
- debugger := self new process: process context: context.
- full
- ifTrue: [debugger openFullNoSuspendLabel: title]
- ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
- debugger errorWasInUIProcess: errorWasInUIProcess.
-
- "Try drawing the debugger tool at least once to avoid freeze."
- Project current world displayWorldSafely.
-
- self clearErrorRecursion]].

process suspend.!

Item was changed:
----- Method: MorphicDebugger class>>openOnMethod:forReceiver:inContext: (in category 'opening') -----
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

+ | guineaPig debugger context |
- | guineaPig debugger debuggerWindow context |
guineaPig :=
[aCompiledMethod
valueWithReceiver: anObject
arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
context := guineaPig suspendedContext.
+
debugger := self new
process: guineaPig
context: context.
+ debugger initializeFull.
+
- debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
"Now step into the expression. But if it is quick (is implemented as a primtiive, e.g. `0')
it will return immediately back to the block that is sent newProcess above. Guard
against that with the check for home being thisContext."
[debugger interruptedContext method == aCompiledMethod]
+ whileFalse: [
+ (guineaPig isNil and: [debugger interruptedContext home == thisContext])
+ ifTrue: [^ Project uiManager inform: 'Nothing to debug; expression is optimized'].
+ debugger send].
+
+ debugger openFullNoSuspendLabel: 'Debug it'.!
- whileFalse:
- [(guineaPig isNil
- and: [debugger interruptedContext home == thisContext]) ifTrue:
- [debuggerWindow delete.
- UIManager default inform: 'Nothing to debug; expression is optimized'.
- ^self].
- debugger send]!

Item was added:
+ ----- Method: MorphicDebugger>>abandon: (in category 'initialize') -----
+ abandon: myWindow
+
+ myWindow delete.!

Item was added:
+ ----- Method: MorphicDebugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: notifierWindow
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullFromNotifier: notifierWindow.
+
+ notifierWindow delete.
+
+ ^ ToolBuilder default
+ open: self
+ label: notifierWindow label!

Item was added:
+ ----- Method: MorphicDebugger>>openFullNoSuspendLabel: (in category 'initialize') -----
+ openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ super openFullNoSuspendLabel: aString.
+
+ ^ ToolBuilder default
+ open: self
+ label: aString!

Item was added:
+ ----- Method: MorphicDebugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+
+ | builder spec |
+ super openNotifierNoSuspendContents: msgString label: label.
+
+ builder := ToolBuilder default.
+ spec := self buildNotifierWith: builder label: label message: msgString.
+
+ ^ ToolBuilder default open: spec!

Item was added:
+ ----- Method: MorphicProject>>interruptCleanUpFor: (in category 'scheduling & debugging') -----
+ interruptCleanUpFor: interruptedProcess
+ "Clean up things in case of a process interrupt."
+
+ super interruptCleanUpFor: interruptedProcess.
+
+ (Preferences eToyFriendly and: [interruptedProcess == self uiProcess])
+ ifTrue: [Project current world stopRunningAll].!

Item was changed:
----- Method: MorphicProject>>interruptName:preemptedProcess: (in category 'scheduling & debugging') -----
interruptName: labelString preemptedProcess: theInterruptedProcess
"Create a Notifier on the active scheduling process with the given label."

| preemptedProcess projectProcess |
+ self uiProcess == Processor activeProcess ifTrue: [
+ ^ self inform: 'You cannot interrupt from within the UI process.\Use a helper process instead.' withCRs translated].
+
ActiveHand ifNotNil:[ActiveHand interrupted].
ActiveWorld := world. "reinstall active globals"
ActiveHand := world primaryHand.
ActiveHand interrupted. "make sure this one's interrupted too"
ActiveEvent := nil.

projectProcess := self uiProcess. "we still need the accessor for a while"
preemptedProcess := theInterruptedProcess ifNil: [Processor preemptedProcess].
"Only debug preempted process if its priority is >= projectProcess' priority"
preemptedProcess priority < projectprocess="" priority="">
ifTrue:[preemptedProcess := projectProcess].
+
preemptedProcess suspend.
+ self interruptCleanUpFor: preemptedProcess.

ToolSet
debugInterruptedProcess: preemptedProcess
label: labelString.!

Item was added:
+ ----- Method: MorphicProject>>startUpActions (in category 'enter') -----
+ startUpActions
+
+ super startUpActions.
+
+ self world install.
+ self world firstHand position: 100@100.!