Marcel Taeumel uploaded a new version of ReleaseBuilder to project The Trunk:
http://source.squeak.org/trunk/ReleaseBuilder-mt.200.mcz
==================== Summary ====================
Name: ReleaseBuilder-mt.200
Author: mt
Time: 25 September 2019, 10:40:18.380838 am
UUID: 27babed0-e564-3247-ae21-049b92db4129
Ancestors: ReleaseBuilder-mt.199
Minor tweaks for constructing MVC->Morphic in the release.
=============== Diff against ReleaseBuilder-mt.199 ===============
Item was changed:
Object subclass: #ReleaseBuilder
instanceVariableNames: ''
classVariableNames: 'DeferredTask NextMajorVersion NextMinorVersion NextTask QAndA'
poolDictionaries: ''
category: 'ReleaseBuilder'!
+ !ReleaseBuilder commentStamp: 'mt 9/25/2019 09:30' prior: 0!
- !ReleaseBuilder commentStamp: 'mt 6/22/2016 18:08' prior: 0!
I'm the script that prepares a trunk image for release.
Just do "ReleaseBuilder doNextStep" repeatedly until the next release is done.
For the final release step:
+ - If you want to try it locally, change #releaseLocally to return true.
+ - Most of the code operates (read-only) on the #buildRepository, which is usually the trunk. For releases, there is a #releaseRepository, to which some package versions will be copied from trunk.!
- - If you want to try it locally, change #localBuild to return true.
- - Most of the code operates (read-only) on the build repository, which is usually the trunk. For releases, there is a release repository, to which some package versions will be copied from trunk.!
Item was removed:
- ----- Method: ReleaseBuilder class>>addMVCParentProject (in category 'scripts - support') -----
- addMVCParentProject
- "The home project is a single Morphic project. Let the home project have a
- parent MVC project as the root of the project tree. The MVC project supports
- emergency debugging in the event of unrecoverable Morphic problems, and
- will fall back on the traditional emergency evaluator if MVC debugging fails.
- If MVC is not installed in the image, then do nothing."
-
- (Smalltalk hasClassNamed:#MVCProject) ifTrue: [ | cls |
- cls := Smalltalk classNamed: #MVCProject.
- ((Project topProject) perform: #isMVC)
- ifFalse: [(cls new name: 'The root project') beTopProject ] ].
- !
Item was removed:
- ----- Method: ReleaseBuilder class>>checkCurrentProjects (in category 'scripts - support') -----
- checkCurrentProjects
-
- Project current isMorphic ifFalse: [
- Warning signal: 'The current project is not Morphic. Please create a new Morphic project, enter it, and restart the release building process.'].
-
- Project allProjects size
- caseOf: {
- [ 1 ] -> [ self addMVCParentProject ] .
- [ 2 ] -> [ ((Project current parent) perform: #isMVC) ifFalse: [ Warning signal: 'Parent of the home project should be an MVC project.' ] ] }
- otherwise: [ Warning signal: 'There should be one home Morphic project with a parent MVC project for fallback debugging.' ] .
-
- "Avoid strange drawing issues."
- Project current world allMorphsDo: [:m | m removeProperty: #errorOnDraw].!
Item was changed:
----- Method: ReleaseBuilder class>>configureDesktop (in category 'scripts') -----
configureDesktop
"Open tools, multimedia content, etc."
self setDisplayExtent: 1024 @ 768.
self setProjectBackground: Color darkGray.
(UserInterfaceTheme named: 'Squeak') apply.
self deleteAllWindows.
self deleteAllOtherMorphs.
+ "Avoid strange drawing issues."
+ Project current world allMorphsDo: [:m | m removeProperty: #errorOnDraw].
+
"Replace docking bar instance in case its code has changed."
Project current removeMainDockingBar.
TheWorldMainDockingBar updateInstances.!
Item was added:
+ ----- Method: ReleaseBuilder class>>configureProjects (in category 'scripts') -----
+ configureProjects
+ "Set up the desired configuration of projects, which might be a single project, multiple projects..."
+
+ | homeProject rootProject |
+ homeProject := Project current.
+ rootProject := homeProject.
+
+ homeProject isMorphic ifFalse: [
+ Warning signal: 'The current project is not Morphic. Please create a new Morphic project, enter it, and restart the release building process.'].
+
+ "The home project is a single Morphic project. Let the home project have a parent MVC project as the root of the project tree. The MVC project supports emergency debugging in the event of unrecoverable Morphic problems, and will fall back on the traditional emergency evaluator if MVC debugging fails. If MVC is not installed in the image, then do nothing."
+ Project current removeAllOtherProjects.
+ (Smalltalk classNamed: #MVCProject)
+ ifNil: [Warning signal: 'MVC must be installed in the release image.']
+ ifNotNil: [:mvc | rootProject := (mvc new name: 'The root project')].
+
+ self
+ assert: homeProject isTopProject;
+ assert: rootProject isTopProject not.
+
+ rootProject beTopProject.
+
+ self
+ assert: rootProject isTopProject;
+ assert: homeProject isTopProject not.
+
+ self
+ assert: rootProject subProjects size = 1;
+ assert: homeProject parent == rootProject;
+ assert: rootProject isMVC.!
Item was removed:
- ----- Method: ReleaseBuilder class>>ensureMorphicTopProject (in category 'scripts - support') -----
- ensureMorphicTopProject
-
- Project current isMorphic ifFalse: [
- Warning signal: 'The current project is not Morphic. A new Morphic project will be created and entered. Please restart the release building process after that.'.
- MorphicProject new enter "current process terminates after this"].!
Item was changed:
----- Method: ReleaseBuilder class>>prepareEnvironment (in category 'preparing') -----
prepareEnvironment
"Prepare everything that should be done for a new image build. Clear caches, passwords, etc."
- "ReleaseBuilder prepareNewBuild"
| balloon |
self
clearCaches;
+ configureProjects;
- checkCurrentProjects;
configureTools;
setPreferences;
configureDesktop.
balloon := self getBalloonForm. "Get now because later the file might be missing."
DeferredTask := [
self openWelcomeWorkspacesWith: balloon.
PreferenceWizardMorph open].
"If you save-and-quit the image after calling #prepareEnvironment, ensure that the next image startup will be fast."
Project current world doOneCycle.!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1101.mcz
==================== Summary ====================
Name: System-mt.1101
Author: mt
Time: 25 September 2019, 10:39:08.307838 am
UUID: c829ba68-0ccb-d34e-aa5a-9a8fe3496e25
Ancestors: System-mt.1100
Fixes #beTopProject, but disconnects visual project-viewer hierarchy from actual project tree. As backup project, avoid cycling between two broken project kinds but only follow project parents.
=============== Diff against System-mt.1100 ===============
Item was changed:
----- Method: Project class>>tryOtherProjectForRecovery: (in category 'error recovery') -----
tryOtherProjectForRecovery: errorMessage
"Try entering the parent project if it uses a different user interface. We determine this by comparing the project's class."
| safeProject nextProject |
nextProject := Project current.
safeProject := nil.
"Search parent projects for one of a different type"
[safeProject notNil or: [nextProject isTopProject]] whileFalse: [
nextProject := nextProject parent.
(Project current isKindOf: nextProject class)
ifFalse: [safeProject := nextProject]].
+
+ "September 2019 --- Do not cycle between Morphic and MVC if both break."
"No suitable parent project found, search all projects for any one of different type."
+ "safeProject ifNil: [Smalltalk garbageCollect.
- safeProject ifNil: [Smalltalk garbageCollect.
safeProject := Project allSubInstances
+ detect: [:proj | (proj isKindOf: Project current class) not] ifNone: []]."
+
- detect: [:proj | (proj isKindOf: Project current class) not] ifNone: []].
safeProject ifNotNil: [:p |
p enterForEmergencyRecovery.
"Active process will usually suspend after this."].
!
Item was changed:
----- Method: Project>>beTopProject (in category 'sub-projects & hierarchy') -----
beTopProject
+ | previousTop |
self isTopProject ifTrue: [^ self].
+ previousTop := self class topProject.
+
self parent deletingProject: self. "Just remove views and refs to me."
+ self addProject: previousTop. "The current top project will be my child now."
+ self setParent: self. "I am the new top project."!
- self addProject: self class topProject.
- self setParent: self.!
Item was changed:
----- Method: Project>>setParent: (in category 'sub-projects & hierarchy') -----
setParent: newParent
- "Notify the current parent to discard views and other references. Avoids deleting that project later if the former parent is deleted. You can only have one parent anyway.."
- (self parent isKindOf: Project) ifTrue: [
- self parent ~= newParent ifTrue: [self parent deletingProject: self].
- ].
-
parentProject := newParent.
nextProject := previousProject := nil.!
Marcel Taeumel uploaded a new version of ReleaseBuilder to project The Trunk:
http://source.squeak.org/trunk/ReleaseBuilder-dtl.198.mcz
==================== Summary ====================
Name: ReleaseBuilder-dtl.198
Author: dtl
Time: 18 September 2019, 10:37:49.461592 pm
UUID: 93409652-4167-4790-a02a-ec5e54f2c036
Ancestors: ReleaseBuilder-mt.197
When preparing a new release image, arrange for the home Morphic project to have a parent MVC project. The MVC project supports emergency debugging in the event of unrecoverable Morphic problems, and will fall back on the traditional emergency evaluator if MVC debugging fails.
=============== Diff against ReleaseBuilder-mt.197 ===============
Item was added:
+ ----- Method: ReleaseBuilder class>>addMVCParentProject (in category 'scripts - support') -----
+ addMVCParentProject
+ "The home project is a single Morphic project. Let the home project have a
+ parent MVC project as the root of the project tree. The MVC project supports
+ emergency debugging in the event of unrecoverable Morphic problems, and
+ will fall back on the traditional emergency evaluator if MVC debugging fails.
+ If MVC is not installed in the image, then do nothing."
+
+ (Smalltalk hasClassNamed:#MVCProject) ifTrue: [ | cls |
+ cls := Smalltalk classNamed: #MVCProject.
+ ((Project topProject) perform: #isMVC)
+ ifFalse: [(cls new name: 'The root project') beTopProject ] ].
+ !
Item was changed:
----- Method: ReleaseBuilder class>>checkCurrentProjects (in category 'scripts - support') -----
checkCurrentProjects
Project current isMorphic ifFalse: [
Warning signal: 'The current project is not Morphic. Please create a new Morphic project, enter it, and restart the release building process.'].
+ Project allProjects size
+ caseOf: {
+ [ 1 ] -> [ self addMVCParentProject ] .
+ [ 2 ] -> [ ((Project current parent) perform: #isMVC) ifFalse: [ Warning signal: 'Parent of the home project should be an MVC project.' ] ] }
+ otherwise: [ Warning signal: 'There should be one home Morphic project with a parent MVC project for fallback debugging.' ] .
- Project allProjects size = 1 ifFalse: [
- Warning signal: 'There should only be one project.'].
"Avoid strange drawing issues."
Project current world allMorphsDo: [:m | m removeProperty: #errorOnDraw].!
Marcel Taeumel uploaded a new version of ToolBuilder-MVC to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-MVC-mt.57.mcz
==================== Summary ====================
Name: ToolBuilder-MVC-mt.57
Author: mt
Time: 24 September 2019, 5:23:47.43786 pm
UUID: 9ac0aed0-2876-c441-aa7b-a682a5963ba5
Ancestors: ToolBuilder-MVC-mt.56
Complements Tools-mt.893:
- adds comments to explain why explicit controller activation is not necessary; check via syntax-error correction if you want
=============== Diff against ToolBuilder-MVC-mt.56 ===============
Item was changed:
----- Method: MVCToolBuilder>>close: (in category 'opening') -----
close: aWidget
+ "Close a previously opened widget. If the widget works as expected, the next controller will be found automatically. No process termination required. See ControlManager >> #activeController:."
+
+ aWidget controller closeAndUnscheduleNoTerminate.!
- "Close a previously opened widget"
- aWidget controller closeAndUnschedule.!
Marcel Taeumel uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-mt.240.mcz
==================== Summary ====================
Name: ST80-mt.240
Author: mt
Time: 24 September 2019, 5:22:22.23186 pm
UUID: 74240c49-e09f-8846-b6d7-8fccdb9dab9e
Ancestors: ST80-mt.239
Complements Tools-mt.893:
- fixes "debug it" for code expressions in workspaces
- adds some warnings for usability
- adds support for proceeding non-ui processes (e.g. "[self halt. 3+4] fork") to keep the UI responsive
- no need for MVCToolBuilder >> #openDebugger: anymore.
- adds detection of recursive errors like Morphic has
=============== Diff against ST80-mt.239 ===============
Item was changed:
----- Method: MVCDebugger 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."
+ | debugger message |
- | debugger |
<primitive: 19> "Simulation guard"
+
+ Project current world inActiveControllerProcess
+ ifTrue: [^ self notify: 'You cannot interrupt from within the active controller process. Use a helper process instead.\\This interrupt request will be aborted.' withCRs translated].
+
debugger := self new.
debugger
process: interruptedProcess
+ controller: (Project current world activeControllerProcess == interruptedProcess
+ ifTrue: [Project current world activeController])
- controller: (ScheduledControllers inActiveControllerProcess == interruptedProcess
- ifTrue: [ScheduledControllers activeController])
context: interruptedProcess suspendedContext.
debugger externalInterrupt: true.
+ ((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;
+ yourself.
+
+ "Since we are in a helper process, #openNoTerminate WILL NOT activate the debugger's controller."
+ Project current world searchForActiveController.
- Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
- ^debugger
- openNotifierContents: nil label: aString;
- yourself
!
Item was changed:
----- Method: MVCDebugger class>>openOn:context:label:contents:fullView: (in category 'opening') -----
+ openOn: process context: context label: title contents: contentsStringOrNil fullView: full
- openOn: process context: context label: title contents: contentsStringOrNil fullView: bool
"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: [
+
+ | 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].
+
+ self setErrorRecursion.
+
+ self informExistingDebugger: context label: title.
+
+ debugger := self new
+ process: process
+ controller: (Project current world activeControllerProcess == process
+ ifTrue: [Project current world activeController])
+ context: context.
+
+ full
+ ifTrue: [debugger openFullNoSuspendLabel: title]
+ ifFalse: [debugger openNotifierNoSuspendContents: contentsStringOrNil label: title].
+
+ "Try drawing the debugger tool at least once to avoid freeze."
+ Project current restoreDisplay.
+
+ self clearErrorRecursion].
+
+ process suspend.!
- | controller debugger |
- controller := ScheduledControllers activeControllerProcess == process
- ifTrue: [ScheduledControllers activeController].
- [Preferences logDebuggerStackToFile
- ifTrue: [Smalltalk logSqueakError: title inContext: context]] on: Error do: [:ex | ex return: nil].
- [debugger := self new
- process: process
- controller: controller
- context: context.
- bool
- ifTrue: [debugger openFullNoSuspendLabel: title]
- ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
- ] on: Error do: [:ex |
- self primitiveError: 'Original error: ' , title asString , '.
- Debugger error: ' , ([ex description]
- on: Error
- do: ['a ' , ex class printString]) , ':'].
- process suspend!
Item was changed:
----- Method: MVCDebugger class>>openOnMethod:forReceiver:inContext: (in category 'opening') -----
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil
+ | guineaPig debugger context inActiveControllerProcess |
+ inActiveControllerProcess := ScheduledControllers inActiveControllerProcess.
+
- | guineaPig debugger debuggerWindow context |
guineaPig :=
[aCompiledMethod
valueWithReceiver: anObject
arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
+ guineaPig := nil. "Spot the return from aCompiledMethod. See below."
+
+ "If we proceed in the debugger, make sure to keep the system responsive."
+ "ScheduledControllers searchForActiveController"] newProcess.
- guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
context := guineaPig suspendedContext.
+
debugger := self new
process: guineaPig
+ controller: nil "None because the guinea pig does *not* relate to the active controller."
- controller: (ScheduledControllers inActiveControllerProcess ifTrue:
- [ScheduledControllers activeController])
context: context.
+ debugger initializeFull. "To make #send work. See below."
+
- 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'.
+ inActiveControllerProcess ifTrue: [Processor terminateActive].!
- whileFalse:
- [(guineaPig isNil
- and: [debugger interruptedContext home == thisContext]) ifTrue:
- [debuggerWindow controller closeAndUnschedule.
- UIManager default inform: 'Nothing to debug; expression is optimized'.
- ^self].
- debugger send]!
Item was added:
+ ----- Method: MVCDebugger>>abandon: (in category 'initialize') -----
+ abandon: aTopView
+
+ aTopView controller closeAndUnscheduleNoTerminate.!
Item was added:
+ ----- Method: MVCDebugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: notifierView
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ | fullView |
+ super openFullFromNotifier: notifierView.
+
+ fullView := ToolBuilder default build: self.
+ fullView label: notifierView label. "Keep the label."
+ fullView controller openNoTerminate.
+
+ notifierView controller closeAndUnscheduleNoTerminate.
+ Processor terminateActive.!
Item was added:
+ ----- Method: MVCDebugger>>openFullNoSuspendLabel: (in category 'initialize') -----
+ openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+
+ | fullView |
+ super openFullNoSuspendLabel: aString.
+
+ fullView := ToolBuilder default build: self.
+ fullView label: aString.
+ fullView controller openNoTerminate.
+
+ ^ fullView!
Item was added:
+ ----- Method: MVCDebugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+
+ | builder spec view |
+ super openNotifierNoSuspendContents: msgString label: label.
+
+ builder := ToolBuilder default.
+ spec := self buildNotifierWith: builder label: label message: msgString.
+
+ view := builder build: spec.
+ view controller openNoTerminate.
+
+ ^ view!
Item was changed:
----- Method: MVCDebugger>>resumeProcess: (in category 'private') -----
resumeProcess: aTopView
+ | hasActiveController |
aTopView erase.
+ savedCursor ifNotNil: [Cursor currentCursor: savedCursor].
+
+ hasActiveController := interruptedProcess isTerminated not and: [interruptedController notNil].
+
- savedCursor
- ifNotNil: [Cursor currentCursor: savedCursor].
interruptedProcess isTerminated ifFalse: [
ScheduledControllers activeControllerNoTerminate: interruptedController andProcess: interruptedProcess].
+
+ Smalltalk installLowSpaceWatcher. "restart low space handler"
+
- "if old process was terminated, just terminate current one"
interruptedProcess := nil. "Before delete, so release doesn't terminate it"
aTopView controller closeAndUnscheduleNoErase.
+
+ hasActiveController
+ ifTrue: [Processor terminateActive]
+ ifFalse: [Project current world searchForActiveController].!
- Smalltalk installLowSpaceWatcher. "restart low space handler"
- Processor terminateActive
- !
Item was changed:
----- Method: MVCProject>>interruptName:preemptedProcess: (in category 'scheduling & debugging') -----
interruptName: labelString preemptedProcess: theInterruptedProcess
"Create a Notifier on the interrupted process with the given label. Make the Notifier the active controller."
+
+ world inActiveControllerProcess ifTrue: [
+ ^ self inform: 'You cannot interrupt from within the UI process.\Use a helper process instead.' withCRs translated].
- theInterruptedProcess suspend.
-
(world activeController ~~ nil and: [world activeController ~~ world screenController]) ifTrue: [
theInterruptedProcess == self uiProcess
ifTrue: [
"Carefully de-emphasis the current window."
world activeController view topView deEmphasizeForDebugger]
ifFalse: [
world activeController controlTerminate]].
+ theInterruptedProcess suspend.
+ self interruptCleanUpFor: theInterruptedProcess.
+
- "This will just scheduleNoTerminate the newly built controller"
ToolSet
debugInterruptedProcess: theInterruptedProcess
+ label: labelString.!
- label: labelString.
-
- world searchForActiveController.!
Item was changed:
----- Method: StandardSystemController>>closeAndUnscheduleNoErase (in category 'scheduling') -----
closeAndUnscheduleNoErase
"Remove the scheduled view from the collection of scheduled views. Set
+ its status to closed but do not erase and do not terminate. For debuggers."
- its status to closed but do not erase."
status := #closed.
ScheduledControllers unschedule: self.
view release.!
Item was changed:
----- Method: StandardSystemController>>closeAndUnscheduleNoTerminate (in category 'scheduling') -----
closeAndUnscheduleNoTerminate
+ "Erase the receiver's view and remove it from the collection of scheduled views, but do not terminate the current process. Useful for clean-up scripts."
- "Erase the receiver's view and remove it from the collection of scheduled views, but do not terminate the current process."
status := #closed.
ScheduledControllers unschedule: self.
view erase.
view release.
!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1100.mcz
==================== Summary ====================
Name: System-mt.1100
Author: mt
Time: 24 September 2019, 5:19:25.04486 pm
UUID: 5150ba88-637f-6d4e-af0f-bf488412cc27
Ancestors: System-mt.1099
Complements Tools-mt.893:
- fixes a bug in system start-up into an MVC project
=============== Diff against System-mt.1099 ===============
Item was changed:
----- Method: AutoStart class>>startUp: (in category 'initialization') -----
startUp: resuming
"The image is either being newly started (resuming is true), or it's just been snapshotted.
If this has just been a snapshot, skip all the startup stuff."
| startupParameters launchers |
self active ifTrue: [^self].
self active: true.
resuming ifFalse: [^self].
startupParameters := Smalltalk namedArguments.
+ Project current startUpActions.
- Project current world ifNotNil: [:w | w install. w firstHand position: 100 @ 100 ].
+ self processUpdates.
- self processUpdates.
launchers := self installedLaunchers collect: [:launcher |
launcher new].
launchers do: [:launcher |
launcher parameters: startupParameters].
launchers do: [:launcher |
Project current addDeferredUIMessage: [launcher startUp]]!
Item was added:
+ ----- Method: Project>>interruptCleanUpFor: (in category 'scheduling & debugging') -----
+ interruptCleanUpFor: interruptedProcess
+ "Clean up things in case of a process interrupt."!
Item was added:
+ ----- Method: Project>>startUpActions (in category 'enter') -----
+ startUpActions
+ "The image is being newly started, not just snapshotted."
+
+ !
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.!
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.893.mcz
==================== Summary ====================
Name: Tools-mt.893
Author: mt
Time: 24 September 2019, 5:16:51.52786 pm
UUID: 40c3d300-00ba-854f-b33f-042b711bc73c
Ancestors: Tools-mt.892
More fixes and code clean-up in debugger:
- make stack sizes a preference(s)
- move code to specific (Morphic/MVC) subclasses
=============== Diff against Tools-mt.892 ===============
Item was changed:
CodeHolder subclass: #Debugger
instanceVariableNames: 'interruptedProcess contextStack contextStackIndex contextStackList receiverInspector contextVariablesInspector externalInterrupt proceedValue selectingPC savedCursor isolationHead failedProject labelString message untilExpression'
+ classVariableNames: 'ContextStackKeystrokes ErrorRecursion ErrorRecursionGuard ErrorReportServer FullStackSize InterruptUIProcessIfBlockedOnErrorInBackgroundProcess NotifierStackSize SavedExtent StackSizeLimit WantsAnnotationPane'
- classVariableNames: 'ContextStackKeystrokes ErrorRecursion ErrorRecursionGuard ErrorReportServer InterruptUIProcessIfBlockedOnErrorInBackgroundProcess SavedExtent WantsAnnotationPane'
poolDictionaries: ''
category: 'Tools-Debugger'!
!Debugger commentStamp: '<historical>' prior: 0!
I represent the machine state at the time of an interrupted process. I also represent a query path into the state of the process. The debugger is typically viewed through a window that views the stack of suspended contexts, the code for, and execution point in, the currently selected message, and inspectors on both the receiver of the currently selected message, and the variables in the current context.
Special note on recursive errors:
Some errors affect Squeak's ability to present a debugger. This is normally an unrecoverable situation. However, if such an error occurs in an isolation layer, Squeak will attempt to exit from the isolation layer and then present a debugger. Here is the chain of events in such a recovery.
* A recursive error is detected.
* The current project is queried for an isolationHead
* Changes in the isolationHead are revoked
* The parent project of isolated project is returned to
* The debugger is opened there and execution resumes.
If the user closes that debugger, execution continues in the outer project and layer. If, after repairing some damage, the user proceeds from the debugger, then the isolationHead is re-invoked, the failed project is re-entered, and execution resumes in that world. !
Item was added:
+ ----- Method: Debugger class>>fullStackSize (in category 'preferences') -----
+ fullStackSize
+
+ <preference: 'Stack Size in Full Debugger'
+ categoryList: #(debug tools)
+ description: 'The number of stack frames to be shown in the full debugger. You can always expand the full stack there.'
+ type: #Number>
+
+ ^ FullStackSize ifNil: [20]!
Item was added:
+ ----- Method: Debugger class>>fullStackSize: (in category 'preferences') -----
+ fullStackSize: aNumber
+
+ FullStackSize := aNumber max: self notifierStackSize.!
Item was added:
+ ----- Method: Debugger class>>lowSpaceChoices (in category 'private') -----
+ lowSpaceChoices
+ "Return a notifier message string to be presented when space is running low."
+
+ ^ 'Warning!! Squeak is almost out of memory!!
+
+ Low space detection is now disabled. It will be restored when you close or proceed from this error notifier. Don''t panic, but do proceed with caution.
+
+ Here are some suggestions:
+
+ If you suspect an infinite recursion (the same methods calling each other again and again), then close this debugger, and fix the problem.
+
+ If you want this computation to finish, then make more space available (read on) and choose "proceed" in this debugger. Here are some ways to make more space available...
+ > Close any windows that are not needed.
+ > Get rid of some large objects (e.g., images).
+ > Leave this window on the screen, choose "save as..." from the screen menu, quit, restart the Squeak VM with a larger memory allocation, then restart the image you just saved, and choose "proceed" in this window.
+
+ If you want to investigate further, choose "debug" in this window. Do not use the debugger "fullStack" command unless you are certain that the stack is not very deep. (Trying to show the full stack will definitely use up all remaining memory if the low-space problem is caused by an infinite recursion!!).
+
+ '
+ !
Item was added:
+ ----- Method: Debugger class>>notifierStackSize (in category 'preferences') -----
+ notifierStackSize
+
+ <preference: 'Stack Size in Notifier Debugger'
+ categoryList: #(debug tools)
+ description: 'If there is no message to be displayed in the notifier, how many stack frames should be visible?'
+ type: #Number>
+
+ ^ NotifierStackSize ifNil: [10]!
Item was added:
+ ----- Method: Debugger class>>notifierStackSize: (in category 'preferences') -----
+ notifierStackSize: anInteger
+
+ NotifierStackSize := anInteger.!
Item was added:
+ ----- Method: Debugger class>>stackSizeLimit (in category 'preferences') -----
+ stackSizeLimit
+
+ <preference: 'Stack Size Limit'
+ categoryList: #(debug tools)
+ description: 'Even when expanding the entire stack, there should be a limit to avoid low-space errors.'
+ type: #Number>
+
+ ^ StackSizeLimit ifNil: [100000]!
Item was added:
+ ----- Method: Debugger class>>stackSizeLimit: (in category 'preferences') -----
+ stackSizeLimit: aNumber
+
+ StackSizeLimit := aNumber max: self fullStackSize.!
Item was changed:
----- Method: Debugger>>abandon: (in category 'context stack menu') -----
abandon: aTopView
"abandon the notifier represented by aTopView"
+
+ self subclassResponsibility.!
- ToolBuilder default close: aTopView!
Item was removed:
- ----- Method: Debugger>>close: (in category 'context stack menu') -----
- close: aScheduledController
- "The argument is a controller on a view of the receiver.
- That view is closed."
-
- aScheduledController close
- !
Item was changed:
----- Method: Debugger>>debug (in category 'notifier menu') -----
debug
+ "Open a full debugger."
+
+ self openFullFromNotifier: self topView.
- "Open a full DebuggerView."
- | topView |
- topView := self topView.
- topView model: nil. "so close won't release me."
- self breakDependents.
- self openFullNoSuspendFrom: topView.
!
Item was changed:
----- Method: Debugger>>debugAt: (in category 'initialize') -----
debugAt: anInteger
+ "Opens a full debugger with the given index selected. See #initializeFull to understand why contextStackIndex is set directly."
+
+ contextStackIndex := anInteger.
+ ^ self debug!
- self toggleContextStackIndex: anInteger.
- ^ self debug.!
Item was added:
+ ----- Method: Debugger>>expandNotifierStack (in category 'context stack (message list)') -----
+ expandNotifierStack
+ "Show a small amount of stack in the context pane. Useful for notifiers."
+
+ self okToChange ifFalse: [^ self].
+ self newStack: (self contextStackTop stackOfSize: self class notifierStackSize).
+ self changed: #contextStackList.
+ !
Item was changed:
----- Method: Debugger>>expandStack (in category 'context stack (message list)') -----
expandStack
+ "Show a substantial amount of stack in the context pane."
- "A Notifier is being turned into a full debugger. Show a substantial amount of stack in the context pane."
+ self okToChange ifFalse: [^ self].
+ self newStack: (self contextStackTop stackOfSize: self class fullStackSize).
+ self changed: #contextStackList.
+ !
- self newStack: (self contextStackTop stackOfSize: 20).
- contextStackIndex := 0.
- receiverInspector := Inspector inspect: nil.
- contextVariablesInspector := ContextVariablesInspector inspect: nil.
- proceedValue := nil!
Item was changed:
----- Method: Debugger>>fullyExpandStack (in category 'context stack (message list)') -----
fullyExpandStack
+ "Expand the stack to include all of it. Well, almost all of it, we better maintain sane limits too."
- "Expand the stack to include all of it, rather than the first four or five contexts.
- Well, almost all of it, we better maintain sane limits too."
self okToChange ifFalse: [^ self].
+ self newStack: (self contextStackTop stackOfSize: self class stackSizeLimit - contextStack size).
+ self changed: #contextStackList.!
- self newStack: (self contextStackTop stackOfSize: contextStack size + 100000).
- self changed: #contextStackList!
Item was changed:
----- Method: Debugger>>initialize (in category 'initialize') -----
initialize
super initialize.
Smalltalk at: #MessageTally ifPresentAndInMemory: [ :tally |
tally terminateTimerProcess].
externalInterrupt := false.
+ selectingPC := true.
+
+ contextStackIndex := 0.!
- selectingPC := true.!
Item was added:
+ ----- Method: Debugger>>initializeFull (in category 'initialize') -----
+ initializeFull
+ "Expand the stack for the full debugger. Create inspectors."
+
+ | oldIndex |
+ oldIndex := contextStackIndex.
+ contextStackIndex := 0.
+
+ self expandStack.
+
+ receiverInspector := Inspector inspect: nil.
+ contextVariablesInspector := ContextVariablesInspector inspect: nil.
+
+ self toggleContextStackIndex: oldIndex.!
Item was removed:
- ----- Method: Debugger>>lowSpaceChoices (in category 'private') -----
- lowSpaceChoices
- "Return a notifier message string to be presented when space is running low."
-
- ^ 'Warning!! Squeak is almost out of memory!!
-
- Low space detection is now disabled. It will be restored when you close or proceed from this error notifier. Don''t panic, but do proceed with caution.
-
- Here are some suggestions:
-
- If you suspect an infinite recursion (the same methods calling each other again and again), then close this debugger, and fix the problem.
-
- If you want this computation to finish, then make more space available (read on) and choose "proceed" in this debugger. Here are some ways to make more space available...
- > Close any windows that are not needed.
- > Get rid of some large objects (e.g., images).
- > Leave this window on the screen, choose "save as..." from the screen menu, quit, restart the Squeak VM with a larger memory allocation, then restart the image you just saved, and choose "proceed" in this window.
-
- If you want to investigate further, choose "debug" in this window. Do not use the debugger "fullStack" command unless you are certain that the stack is not very deep. (Trying to show the full stack will definitely use up all remaining memory if the low-space problem is caused by an infinite recursion!!).
-
- '
- !
Item was added:
+ ----- Method: Debugger>>openFullFromNotifier: (in category 'initialize') -----
+ openFullFromNotifier: topView
+ "Create a full debugger with the given label. Subclasses should complete this procedure."
+
+ self initializeFull.
+
+ topView model: nil. "so close won't release me."
+ self breakDependents.!
Item was removed:
- ----- Method: Debugger>>openFullNoSuspendFrom: (in category 'initialize') -----
- openFullNoSuspendFrom: topView
- "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
-
- | oldContextStackIndex |
- oldContextStackIndex := contextStackIndex.
- self expandStack. "Sets contextStackIndex to zero."
- ^[ToolBuilder default openDebugger: self label: topView label closing: topView] ensure:
- [self toggleContextStackIndex: oldContextStackIndex]!
Item was changed:
----- Method: Debugger>>openFullNoSuspendLabel: (in category 'initialize') -----
openFullNoSuspendLabel: aString
+ "Create, schedule and answer a full debugger with the given label. Subclasses should complete this procedure."
- "Create, schedule and answer a full debugger with the given label. Do not terminate the current active process."
+ self initializeFull.!
- | oldContextStackIndex |
- oldContextStackIndex := contextStackIndex.
- self expandStack. "Sets contextStackIndex to zero."
- ^[ToolBuilder default openDebugger: self label: aString] ensure:
- [self toggleContextStackIndex: oldContextStackIndex]!
Item was removed:
- ----- Method: Debugger>>openNotifierContents:label: (in category 'initialize') -----
- openNotifierContents: msgString label: label
- "Create, schedule and answer 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 process has not been suspended. The sender will do this."
- | msg builder spec |
-
- Sensor flushKeyboard.
- savedCursor := Cursor currentCursor.
- Cursor currentCursor: Cursor normal.
- msg := (label beginsWith: 'Space is low')
- ifTrue: [self lowSpaceChoices, (msgString ifNil: [String empty])]
- ifFalse: [msgString].
- builder := ToolBuilder default.
- spec := self buildNotifierWith: builder label: label message: msg.
- self expandStack.
- ^ builder openDebugger: spec!
Item was added:
+ ----- Method: Debugger>>openNotifierNoSuspendContents:label: (in category 'initialize') -----
+ openNotifierNoSuspendContents: msgString label: label
+ "Create, schedule and answer 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 process has not been suspended. The sender will do this."
+
+ Sensor flushKeyboard.
+ savedCursor := Cursor currentCursor.
+ Cursor currentCursor: Cursor normal.
+
+ self expandNotifierStack.!
Item was removed:
- ----- Method: Debugger>>release (in category 'initialize') -----
- release
-
- self windowIsClosing.
- super release.
- !