[squeak-dev] The Trunk: Tools-ct.1149.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu May 5 16:24:58 UTC 2022
Christoph Thiede uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-ct.1149.mcz
==================== Summary ====================
Name: Tools-ct.1149
Author: ct
Time: 5 May 2022, 6:24:40.020816 pm
UUID: dff67dfa-826f-6a48-948a-febe229528df
Ancestors: Tools-xw.1147, Tools-ct.1109
Merges and revises Tools-ct.1109 (protects the debugger from debugging the active process).
Revision: Instead of stepping the model, disable stepping all buttons upon the first click when the interrupted process is not ready. See #shouldNotStep for an example situation.
Thanks to Marcel for the feedback!
=============== Diff against Tools-xw.1147 ===============
Item was changed:
----- Method: Debugger>>customButtonSpecs (in category 'initialize') -----
customButtonSpecs
"Answer an array of elements of the form wording, selector, help-message, that characterize the custom button row of a debugger."
| list |
list := #(('Proceed' proceed 'Close the debugger and proceed.' interruptedProcessShouldResume)
('Restart' restart 'Reset this context to its start.')
+ ('Into' stepInto 'step Into message sends' interruptedProcessIsReady)
+ ('Over' stepOver 'step Over message sends' interruptedProcessIsReady)
+ ('Through' stepThrough 'step into a block' interruptedProcessIsReady)
- ('Into' stepInto 'step Into message sends' interruptedProcessIsActive)
- ('Over' stepOver 'step Over message sends' interruptedProcessIsActive)
- ('Through' stepThrough 'step into a block' interruptedProcessIsActive)
('Full Stack' showFullStack 'show full stack')
('Where' showWhere 'select current pc range')
('Tally It' tally 'evaluate current selection and measure the time')).
(Preferences restartAlsoProceeds and: [self interruptedProcessShouldResume]) ifTrue:
[list := list collect: [:each |
each second == #restart
ifTrue: [each copy
at: 1 put: 'Proceed Here';
at: 3 put: 'Proceed from the beginning of this context.';
yourself]
ifFalse: [each second == #proceed
ifTrue: [each copy
at: 1 put: 'Proceed Top';
at: 3 put: 'Proceed from the current top context.';
yourself]
ifFalse: [each]]]].
^ list!
Item was changed:
----- Method: Debugger>>doStep (in category 'context stack menu') -----
doStep
"Send the selected message in the accessed method, and regain control
after the invoked method returns."
| currentContext newContext |
self okToChange ifFalse: [^ self].
+ self interruptedProcessIsReady ifFalse: [^ self shouldNotStep].
self checkContextSelection.
currentContext := self selectedContext.
newContext := self handleLabelUpdatesIn: [interruptedProcess completeStep: currentContext]
whenExecuting: currentContext.
+ interruptedProcess ifNil: [^ self shouldNotStep].
newContext == currentContext ifTrue:
[newContext := interruptedProcess stepToSendOrReturn].
+ self updateProcess.
self contextStackIndex > 1
ifTrue: [self resetContext: newContext]
ifFalse:
[newContext == currentContext
ifTrue: [self changed: #contentsSelection.
self updateInspectors]
+ ifFalse: [self resetContext: newContext]].!
- ifFalse: [self resetContext: newContext]].
- !
Item was changed:
----- Method: Debugger>>doStepUntil: (in category 'context stack menu') -----
doStepUntil: condition
"Step until the given condition evaluates to other than false, reporting an error it if does not evaluate to true.
If shift is pressed when the expression is supplied, don't update the UI. If shift is pressed while stepping, stop stepping. Using a user interrupt to break out would be more natural but Squeak currently doesn't provide a UserInterrupt exception. It should do."
| currentContext newContext value lastUpdate updateUI breakOnShift |
self okToChange ifFalse: [^ self].
+ self interruptedProcessIsReady ifFalse: [^ self shouldNotStep].
self checkContextSelection.
currentContext := newContext := self selectedContext.
lastUpdate := Time millisecondClockValue.
updateUI := breakOnShift := Sensor shiftPressed not.
Cursor execute showWhile: [[
newContext == currentContext
and: [currentContext willReturn not
and: [(value := condition value) == false]] ] whileTrue: [
self
handleLabelUpdatesIn: [newContext := interruptedProcess completeStep: currentContext]
whenExecuting: currentContext.
+ interruptedProcess ifNil: [^ self shouldNotStep].
newContext == currentContext ifTrue: [
newContext := interruptedProcess stepToSendOrReturn.
self resetContext: newContext changeContents: false].
Time millisecondClockValue - lastUpdate > 250 "ms" ifTrue: [
updateUI ifTrue: [
self changed: #contentsSelection.
Project current world displayWorldSafely].
breakOnShift
ifTrue: [Sensor shiftPressed ifTrue: [
self changed: #contentsSelection.
self updateInspectors.
^self]]
ifFalse: [Sensor shiftPressed ifFalse: [breakOnShift := true]].
lastUpdate := Time millisecondClockValue] ]].
+ self updateProcess.
self contextStackIndex > 1
ifTrue: [self resetContext: newContext]
ifFalse:
[newContext == currentContext
ifTrue: [self changed: #contentsSelection; updateInspectors]
ifFalse: [self resetContext: newContext]].
+ ^ value!
- ^ value
- !
Item was removed:
- ----- Method: Debugger>>interruptedProcessIsActive (in category 'testing') -----
- interruptedProcessIsActive
- ^interruptedProcess isTerminated not!
Item was added:
+ ----- Method: Debugger>>interruptedProcessIsReady (in category 'testing') -----
+ interruptedProcessIsReady
+
+ ^ interruptedProcess notNil
+ and: [interruptedProcess isSuspended "do not debug the active process"]
+ and: [interruptedProcess isTerminated not]!
Item was changed:
----- Method: Debugger>>interruptedProcessShouldResume (in category 'testing') -----
interruptedProcessShouldResume
+
+ ^ self interruptedProcessIsReady and: [interruptedProcess shouldResumeFromDebugger]!
- ^ interruptedProcess shouldResumeFromDebugger!
Item was changed:
----- Method: Debugger>>removeMessage (in category 'context stack menu') -----
removeMessage
| oldContext method cleanIndex |
self okToChange ifFalse: [^ false].
contextStackIndex isZero ifTrue: [^ false].
oldContext := self selectedContext.
method := oldContext method.
cleanIndex := self findCleanHomeBelow: method.
contextStack at: cleanIndex ifAbsent: [
self inform: 'Sender of method not found on stack, can''t remove message'.
^ false].
+ self interruptedProcessIsReady ifFalse: [^ self shouldNotStep].
(self confirm: 'I will have to revert to the sender of this message. Is that OK?')
ifFalse: [^ false].
super removeMessage ifFalse: [^ false].
self
contextStackIndex: cleanIndex oldContextWas: oldContext;
tryRestartFrom: self selectedContext.
^ true!
Item was changed:
----- Method: Debugger>>resetContext:changeContents: (in category 'private') -----
resetContext: aContext changeContents: aBoolean
"Used when a new context becomes top-of-stack, for instance when the
method of the selected context is re-compiled, or the simulator steps or
returns to a new method. There is room for much optimization here, first
to save recomputing the whole stack list (and text), and secondly to avoid
recomposing all that text (by editing the paragraph instead of recreating it)."
| oldContext |
oldContext := self selectedContext.
self newStack: (aContext ifNil: [oldContext]) contextStack.
+ self changed: #contextStackList.
- self changed: #contextStackList; changed: #interruptedProcessIsActive.
self contextStackIndex: 1 oldContextWas: oldContext.
+ self updateProcess.
+ aBoolean ifTrue: [self contentsChanged].!
- aBoolean ifTrue: [self contentsChanged].
- !
Item was changed:
----- Method: Debugger>>restart (in category 'context stack menu') -----
restart
"Proceed from the initial state of the currently selected context. The
argument is a controller on a view of the receiver. That view is closed."
"Closing now depends on a preference #restartAlsoProceeds - hmm 9/7/2001 16:46"
| unwindError |
self okToChange ifFalse: [^ self].
+ interruptedProcess isSuspended ifFalse: [^ self shouldNotStep].
self checkContextSelection.
unwindError := self tryRestartFrom: self selectedContext.
((Preferences restartAlsoProceeds
and: [unwindError not])
and: [self interruptedProcessShouldResume])
ifTrue: [self proceed].!
Item was changed:
----- Method: Debugger>>send (in category 'context stack menu') -----
send
"Send the selected message in the accessed method, and take control in
the method invoked to allow further step or send."
self okToChange ifFalse: [^ self].
+ self interruptedProcessIsReady ifFalse: [^ self shouldNotStep].
self checkContextSelection.
interruptedProcess step: self selectedContext.
+ interruptedProcess ifNil: [^ self shouldNotStep].
+ self resetContext: interruptedProcess stepToSendOrReturn.!
- self resetContext: interruptedProcess stepToSendOrReturn.
- !
Item was added:
+ ----- Method: Debugger>>shouldNotStep (in category 'private') -----
+ shouldNotStep
+ "An illegal attempt was to step an unready process. Update the enablement of stepping buttons and trigger a visual indication.
+
+ For instance, this situation can be triggered by this:
+ [self currentHand lastEvent shiftPressed] yourself
+ whileFalse: [Project current world doOneCycleNow].
+ Debug it, step over #whileFalse: and step over again. Move your cursor while pressing shift to continue."
+
+ self
+ changed: #interruptedProcessIsReady;
+ changed: #interruptedProcessShouldResume.
+
+ ^ self changed: #flash!
Item was changed:
----- Method: Debugger>>stepIntoBlock (in category 'context stack menu') -----
stepIntoBlock
"Send messages until you return to the present method context.
Used to step into a block in the method."
| currentContext newContext |
self okToChange ifFalse: [^ self].
+ self interruptedProcessIsReady ifFalse: [^ self shouldNotStep].
self checkContextSelection.
currentContext := self selectedContext.
self handleLabelUpdatesIn:
[interruptedProcess stepToHome: currentContext]
whenExecuting: self selectedContext.
+ interruptedProcess ifNil: [^ self shouldNotStep].
newContext := interruptedProcess stepToSendOrReturn.
+ self updateProcess.
self contextStackIndex > 1
ifTrue: [self resetContext: newContext]
ifFalse:
[newContext == currentContext
ifTrue: [self changed: #contentsSelection.
self updateInspectors]
ifFalse: [self resetContext: newContext]].!
Item was added:
+ ----- Method: Debugger>>updateProcess (in category 'private') -----
+ updateProcess
+
+ self
+ changed: #interruptedProcessIsReady;
+ changed: #interruptedProcessShouldResume.!
More information about the Squeak-dev
mailing list
|