'From Squeak5.3beta of 18 January 2020 [latest update: #19328] on 20 January 2020 at 3:20:48 pm'! !Debugger methodsFor: 'code pane' stamp: 'ct 1/20/2020 01:10'! pcRange "Answer the indices in the source code for the method corresponding to the selected context's program counter value." | ctxt | (selectingPC and: [contextStackIndex ~= 0]) ifFalse: [^1 to: 0]. (ctxt := self selectedContext) isDead ifTrue: [^1 to: 0]. ^ self contentsSymbol = #decompile ifTrue: [ | allLines lineIndex linesBefore start | allLines := self contents asString lines. lineIndex := allLines findFirst: [:line | line asNumber = ctxt pc]. linesBefore := allLines first: lineIndex - 1. start := (linesBefore detectSum: #size) + linesBefore size "for the newlines". start + 1 to: start + (allLines at: lineIndex) size] ifFalse: [ ctxt debuggerMap rangeForPC: ctxt pc in: ctxt method contextIsActiveContext: contextStackIndex = 1]! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 01:15'! doStep "Send the selected message in the accessed method, and regain control after the invoked method returns." | currentContext newContext | self okToChange ifFalse: [^ self]. self checkContextSelection. currentContext := self selectedContext. newContext := self handleLabelUpdatesIn: [interruptedProcess completeStep: currentContext] whenExecuting: currentContext. newContext == currentContext ifTrue: [newContext := self stepToStatement]. self contextStackIndex > 1 ifTrue: [self resetContext: newContext] ifFalse: [newContext == currentContext ifTrue: [self changed: #contentsSelection. self updateInspectors] ifFalse: [self resetContext: newContext]]. ! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 01:14'! 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 checkContextSelection. interruptedProcess step: self selectedContext. self resetContext: self stepToStatement. ! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 15:20'! simulateStep | sender | self okToChange ifFalse: [^ self]. self checkContextSelection. sender := self interruptedProcess suspendedContext. self interruptedProcess install: [sender step] asContext; runUntil: [:ctxt | ctxt selector = #step and: [ctxt receiver == sender]]. self interruptedProcess suspendedContext privSender: sender; insertSender: [ self flag: #bug. "Due to a known error, you MUST press Into to step into and out of #jump until you reached user code again, otherwise your image will crash. Sorry for the inconvenience!! See http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFrom-td5107263.html" thisContext sender jump] asContext. self resetContext: self stepToStatement.! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 01:14'! stepIntoBlock "Send messages until you return to the present method context. Used to step into a block in the method." self handleLabelUpdatesIn: [interruptedProcess stepToHome: self selectedContext] whenExecuting: self selectedContext. self resetContext: self stepToStatement.! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 01:16'! stepToStatement self contentsSymbol = #decompile ifTrue: [^ interruptedProcess suspendedContext]. ^ interruptedProcess stepToSendOrReturn! ! !Debugger methodsFor: 'context stack menu' stamp: 'ct 1/20/2020 01:14'! tryRestartFrom: context "Try to restart from the initial state of the context. Return whether an unwind error occurred." | actualContext unwindError | actualContext := interruptedProcess popTo: context. unwindError := actualContext ~= context. unwindError ifFalse: [ interruptedProcess restartTop. self stepToStatement]. self resetContext: actualContext. ^ unwindError! ! !Debugger methodsFor: 'initialize' stamp: 'ct 1/20/2020 01:19'! 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' interruptedProcessIsActive) ('Over' stepOver 'step Over message sends' interruptedProcessIsActive) ('Through' stepThrough 'step into a block' interruptedProcessIsActive) ('Simulate' simulateStep 'simulate bytecode step' 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! ! !Debugger methodsFor: 'toolbuilder' stamp: 'ct 1/20/2020 00:49'! contentsSymbolQuints ^ super contentsSymbolQuints select: [:quint | #(source decompile) includes: quint first]! ! !Debugger methodsFor: 'context stack - message list' stamp: 'ct 1/20/2020 15:15'! selectedMessage "Answer the source code of the currently selected context." | aContext | aContext := self selectedContext. ^ contents := self contentsSymbol = #decompile ifTrue: [aContext method symbolic flag: #ct "better reuse decompiledSourceIntoContents"] ifFalse: [aContext debuggerMap sourceText asText makeSelectorBoldIn: aContext home receiver class]! ! Debugger removeSelector: #wantsCodeProvenanceButton!