Context inaccurate in debugger
arning at charm.net
Wed Apr 26 16:19:08 UTC 2000
This has puzzled me for a long time and now I see what was wrong.
===== code follows =====
'From Squeak2.8alpha of 13 January 2000 [latest update: #2040] on 26 April 2000 at 12:09:57 pm'!
"Change Set: UnusedTempFix
Date: 26 April 2000
Author: Bob Arning
This corrects (hopefully without breaking anything else) a problem with the Parser: sometimes you look at a method in the debugger and the contents of method temporary variables (lower right pane) are wrong. Values that should clearly be in the slot n are showing up further down the list.
How it happens:
1. A method is compiled and bytecodes generated.
2. The parser detects unused method temps and removes them after getting confirmation.
3. Sometime later a debugger encounters this method and tries to show the context variables. The problem is that the code was compiled before the removal of the temps from the source, but the debugger is using the current source to figure out where each variable is in the context and may well get it wrong.
The fix is to recompile the method after the unused varaibale have been deleted from the source, thus ensuring consistency"!
Notification subclass: #ParserRemovedUnusedTemps
category: 'System-Exceptions Tests'!
!Parser methodsFor: 'public access' stamp: 'RAA 4/26/2000 11:59'!
parse: sourceStream class: class noPattern: noPattern context: ctxt notifying: req ifFail: aBlock
"Answer a MethodNode for the argument, sourceStream, that is the root of
a parse tree. Parsing is done with respect to the argument, class, to find
instance, class, and pool variables; and with respect to the argument,
ctxt, to find temporary variables. Errors in parsing are reported to the
argument, req, if not nil; otherwise aBlock is evaluated. The argument
noPattern is a Boolean that is true if the the sourceStream does not
contain a method header (i.e., for DoIts)."
| meth repeatNeeded startPos myStream |
myStream _ sourceStream.
repeatNeeded _ false.
self init: myStream notifying: req failBlock: [^aBlock value].
doitFlag _ noPattern.
encoder _ Encoder new init: class context: ctxt notifying: self.
meth _ self method: noPattern context: ctxt.
repeatNeeded _ true.
myStream _ ReadStream on: requestor text string
encoder _ failBlock _ requestor _ parseNode _ nil. "break cycles & mitigate refct overflow"
!Parser methodsFor: 'error correction' stamp: 'RAA 4/26/2000 11:05'!
| str end start madeChanges |
madeChanges _ false.
str _ requestor text string.
((tempsMark between: 1 and: str size)
and: [(str at: tempsMark) = $|]) ifFalse: [^ self].
encoder unusedTempNames do:
((PopUpMenu labels: 'yes\no' withCRs) startUpWithCaption:
((temp , ' appears to be
unused in this method.
OK to remove it?') asText makeBoldFrom: 1 to: temp size))
[(encoder encodeVariable: temp) isUndefTemp
[end _ tempsMark.
["Beginning at right temp marker..."
start _ end - temp size + 1.
end < temp size or: [temp = (str copyFrom: start to: end)
and: [(str at: start-1) isSeparator & (str at: end+1) isSeparator]]]
["Search left for the unused temp"
end _ requestor nextTokenFrom: end direction: -1].
end < temp size ifFalse:
[(str at: start-1) = $ ifTrue: [start _ start-1].
requestor correctFrom: start to: end with: ''.
str _ str copyReplaceFrom: start to: end with: ''.
madeChanges _ true.
tempsMark _ tempsMark - (end-start+1)]]
'You''ll first have to remove the
statement where it''s stored into']]].
madeChanges ifTrue: [ParserRemovedUnusedTemps signal].! !
More information about the Squeak-dev