The Trunk: ST80-mt.240.mcz

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

The Trunk: ST80-mt.240.mcz

commits-2
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.
  !