[Cuis-dev] Browser tools for MessageTracer
Mariano Montone
marianomontone at gmail.com
Sat Nov 5 16:52:33 PDT 2022
Juan,
I attach a new version of MessageTracer package that adds menus and
tools for managing traced messages from system browser.
Can you merge please? (overwrite the package file in
Cuis/DevPackages/Tools directory)
Thanks,
Mariano
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20221105/03eca86b/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Captura de pantalla -2022-11-05 20-47-08.png
Type: image/png
Size: 82612 bytes
Desc: not available
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20221105/03eca86b/attachment-0001.png>
-------------- next part --------------
'From Cuis 6.0 [latest update: #5552] on 5 November 2022 at 8:43:24 pm'!
'Description Utility library for tracing the sending of messages.'!
!provides: 'MessageTracer' 1 35!
SystemOrganization addCategory: 'MessageTracer-Tests'!
SystemOrganization addCategory: 'MessageTracer'!
!classDefinition: #MessageTracerWindow category: 'MessageTracer'!
SystemWindow subclass: #MessageTracerWindow
instanceVariableNames: 'messageListIndex tracedMessage'
classVariableNames: ''
poolDictionaries: ''
category: 'MessageTracer'!
!classDefinition: 'MessageTracerWindow class' category: 'MessageTracer'!
MessageTracerWindow class
instanceVariableNames: ''!
!classDefinition: #MessageTracerTestSubject category: 'MessageTracer-Tests'!
Object subclass: #MessageTracerTestSubject
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'MessageTracer-Tests'!
!classDefinition: 'MessageTracerTestSubject class' category: 'MessageTracer-Tests'!
MessageTracerTestSubject class
instanceVariableNames: ''!
!classDefinition: #MessageTracer category: 'MessageTracer'!
Object subclass: #MessageTracer
instanceVariableNames: 'outputStream tracing'
classVariableNames: ''
poolDictionaries: ''
category: 'MessageTracer'!
!classDefinition: 'MessageTracer class' category: 'MessageTracer'!
MessageTracer class
instanceVariableNames: 'singleton'!
!classDefinition: #TracedMethodWrapper category: 'MessageTracer'!
Object subclass: #TracedMethodWrapper
instanceVariableNames: 'compiledMethod methodClass enabled when'
classVariableNames: 'InvocationLevel'
poolDictionaries: ''
category: 'MessageTracer'!
!classDefinition: 'TracedMethodWrapper class' category: 'MessageTracer'!
TracedMethodWrapper class
instanceVariableNames: ''!
!MessageTracerWindow commentStamp: '<historical>' prior: 0!
A morphic tool for managing traced messages.!
!MessageTracer commentStamp: 'MM 7/29/2022 12:51:13' prior: 0!
I provide an api for tracing the sending of messages.
The message traces are sent to the Transcript.
For example, open a Transcript and evaluate:
subject _ MessageTracerTestSubject new.
subject foo.
MessageTracer trace: MessageTracerTestSubject selector: #foo.
subject foo.
MessageTracer untrace: MessageTracerTestSubject selector: #foo.
MessageTracerTestSubject trace: #add:to:.
subject add: 4 to: 5.
MessageTracerTestSubject trace: #fact:.
subject fact: 5.
MessageTracerTestSubject trace: #fib:.
subject fib: 10.
MessageTracerTestSubject untrace: #fib:.!
!MessageTracerWindow methodsFor: 'actions' stamp: 'MM 11/5/2022 20:20:08'!
browseSelectedMessage
tracedMessage ifNotNil: [
. BrowserWindow fullOnClass: tracedMessage compiledMethod methodClass
selector: tracedMessage compiledMethod selector]! !
!MessageTracerWindow methodsFor: 'actions' stamp: 'MM 11/5/2022 20:25:25'!
untraceAll
model untraceAll.
self changed: #messageList! !
!MessageTracerWindow methodsFor: 'actions' stamp: 'MM 11/5/2022 20:27:32'!
untraceSelectedMessage
model untrace: tracedMessage.
self changed: #messageList! !
!MessageTracerWindow methodsFor: 'initialization' stamp: 'MM 11/5/2022 18:51:06'!
initialize
super initialize.
messageListIndex _ 0.! !
!MessageTracerWindow methodsFor: 'GUI building' stamp: 'MM 11/5/2022 20:43:11'!
buildMorphicWindow
| messageList actionsRow |
messageList _ PluggableListMorph
model: self
listGetter: #messageList
indexGetter: #messageListIndex
indexSetter: #messageListIndex:.
layoutMorph addMorphUseAll: messageList.
actionsRow _ LayoutMorph newRow.
actionsRow addMorph: (PluggableButtonMorph model: self action: #browseSelectedMessage label: 'Browse').
actionsRow addMorph: (PluggableButtonMorph model: self action: #untraceSelectedMessage label: 'Untrace').
actionsRow addMorph: (PluggableButtonMorph model: self action: #untraceAll label: 'Untrace all').
layoutMorph addMorph: actionsRow fixedHeight: 30.! !
!MessageTracerWindow methodsFor: 'GUI building' stamp: 'MM 11/5/2022 18:59:20'!
initialExtent
^ 400 at 300! !
!MessageTracerWindow methodsFor: 'GUI building' stamp: 'MM 11/5/2022 20:41:23'!
update: anObject
self changed: #messageList! !
!MessageTracerWindow methodsFor: 'accessing' stamp: 'MM 11/5/2022 19:03:32'!
messageList
^ model tracing collect: [:traceWrapper |
traceWrapper compiledMethod methodClass name asString , '>>', traceWrapper selector asString]! !
!MessageTracerWindow methodsFor: 'accessing' stamp: 'MM 11/5/2022 18:51:14'!
messageListIndex
"Answer the value of messageListIndex"
^ messageListIndex! !
!MessageTracerWindow methodsFor: 'accessing' stamp: 'MM 11/5/2022 20:16:34'!
messageListIndex: anObject
"Set the value of messageListIndex"
messageListIndex := anObject.
tracedMessage _ nil.
anObject ifNotNil: [
anObject isZero ifFalse: [
tracedMessage _ model tracing at: anObject]]
! !
!MessageTracerWindow class methodsFor: 'as yet unclassified' stamp: 'MM 11/5/2022 18:56:30'!
open
^ self open: MessageTracer singleton label: 'Tracing'! !
!MessageTracerTestSubject methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 13:33:48'!
add: x to: y
^ x + y! !
!MessageTracerTestSubject methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:51:53'!
bar
^ 'bar'! !
!MessageTracerTestSubject methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 13:36:43'!
fact: x
^ x = 1 ifTrue: [x]
ifFalse: [x * (self fact: x - 1)]! !
!MessageTracerTestSubject methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 13:39:28'!
fib: x
^ x <= 1 ifTrue: [x]
ifFalse: [(self fib: x - 1) + (self fib: x - 2)]! !
!MessageTracerTestSubject methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:51:47'!
foo
^ 'foo'! !
!MessageTracer methodsFor: 'accessing' stamp: 'MM 6/17/2022 12:35:45'!
outputStream
"Answer the value of outputStream"
^ outputStream! !
!MessageTracer methodsFor: 'accessing' stamp: 'MM 6/17/2022 12:35:45'!
outputStream: anObject
"Set the value of outputStream"
outputStream := anObject! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 20:32:36'!
toggleTrace: aCompiledMethod
(aCompiledMethod isKindOf: TracedMethodWrapper)
ifTrue: [self untrace: aCompiledMethod]
ifFalse: [self trace: aCompiledMethod]! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 20:40:43'!
trace: aCompiledMethod
|methodWrapper |
"If breakpoint already installed, setup and enable."
aCompiledMethod class isCompiledMethodClass ifFalse: [
(aCompiledMethod isKindOf: TracedMethodWrapper)
ifTrue: [
aCompiledMethod when: #around; enable.
^ self]].
"Install a new trace wrapper"
methodWrapper _ TracedMethodWrapper on: aCompiledMethod methodClass selector: aCompiledMethod selector.
methodWrapper install.
tracing add: methodWrapper.
self changed.! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 18:12:34'!
trace: aClass selector: selector
|compiledMethod |
compiledMethod _ aClass compiledMethodAt: selector.
^ self trace: compiledMethod! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 20:40:54'!
untrace: aCompiledMethod
aCompiledMethod class isCompiledMethodClass ifFalse: [
(aCompiledMethod isKindOf: TracedMethodWrapper)
ifTrue: [
aCompiledMethod uninstall.
tracing remove: aCompiledMethod.
self changed.
^ self]]! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 20:21:48'!
untrace: aClass selector: selector
|compiledMethod |
compiledMethod _ aClass compiledMethodAt: selector.
^ self untrace: compiledMethod! !
!MessageTracer methodsFor: 'api' stamp: 'MM 11/5/2022 20:42:06'!
untraceAll
tracing do: [:tracedMethod |
tracedMethod uninstall].
tracing _ OrderedCollection new.
self changed.! !
!MessageTracer methodsFor: 'initialization' stamp: 'MM 6/17/2022 12:54:23'!
initialize
tracing _ OrderedCollection new.
outputStream _ Transcript! !
!MessageTracer methodsFor: 'as yet unclassified' stamp: 'MM 11/5/2022 18:21:00'!
tracing
^ tracing! !
!MessageTracer class methodsFor: 'as yet unclassified' stamp: 'MM 11/5/2022 18:41:23'!
messageListMenuOptions
^`{
{
#itemGroup -> 25.
#itemOrder -> 30.
#label -> 'toggle tracing'.
#object -> #model.
#selector -> #toggleMessageTracing.
#icon -> #debugIcon
} asDictionary.
{
#itemGroup -> 25.
#itemOrder -> 30.
#label -> 'show traced'.
#object -> #model.
#selector -> #showTracedMessages.
#icon -> #displayIcon.
} asDictionary.
{
#itemGroup -> 25.
#itemOrder -> 30.
#object -> MessageTracer.
#label -> 'untrace all'.
#selector -> #untraceAll.
#icon -> #debugIcon.
} asDictionary.
}`! !
!MessageTracer class methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:35:28'!
outputStream
^ self singleton outputStream! !
!MessageTracer class methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:35:13'!
singleton
^ singleton ifNil: [singleton _ self new]! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 11/5/2022 20:33:11'!
toggleTrace: aCompiledMethod
self singleton toggleTrace: aCompiledMethod! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 11/5/2022 18:25:04'!
trace: aCompiledMethod
self singleton trace: aCompiledMethod! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 6/17/2022 12:53:20'!
trace: aClass selector: aSelector
self singleton trace: aClass selector: aSelector! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 11/5/2022 18:21:23'!
tracing
^ self singleton tracing! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 11/5/2022 20:22:24'!
untrace: aCompiledMethod
self singleton untrace: aCompiledMethod! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 6/17/2022 13:02:37'!
untrace: aClass selector: aSelector
self singleton untrace: aClass selector: aSelector! !
!MessageTracer class methodsFor: 'api' stamp: 'MM 6/17/2022 13:44:35'!
untraceAll
self singleton untraceAll! !
!TracedMethodWrapper methodsFor: 'initialization' stamp: 'MM 6/17/2022 12:30:37'!
initialize: aClass selector: aSelector
methodClass _ aClass.
compiledMethod _ aClass compiledMethodAt: aSelector.
enabled _ true.
when _ #around
! !
!TracedMethodWrapper methodsFor: 'installation' stamp: 'MM 6/17/2022 12:59:34'!
enable
enabled _ true! !
!TracedMethodWrapper methodsFor: 'installation' stamp: 'MM 6/17/2022 12:58:58'!
install
methodClass
addSelectorSilently: compiledMethod selector
withMethod: self! !
!TracedMethodWrapper methodsFor: 'installation' stamp: 'MM 6/17/2022 12:59:25'!
toggle
enabled _ enabled not! !
!TracedMethodWrapper methodsFor: 'installation' stamp: 'MM 6/17/2022 12:59:15'!
uninstall
methodClass
addSelectorSilently: compiledMethod selector
withMethod: compiledMethod! !
!TracedMethodWrapper methodsFor: 'testing' stamp: 'MM 6/17/2022 12:59:42'!
enabled
^ enabled! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 12:57:46'!
decreaseInvocationLevel
InvocationLevel _ InvocationLevel - 1.! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 6/17/2022 12:03:30'!
doesNotUnderstand: aMessage
^ aMessage sendTo: compiledMethod! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:11:57'!
increaseInvocationLevel
InvocationLevel _ self invocationLevel + 1.! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:06:06'!
invocationLevel
^ InvocationLevel ifNil: [1]! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:01:01'!
outputMethodEntry: aReceiver arguments: arguments
|stream|
stream _ MessageTracer outputStream.
self printIndentation: stream.
stream nextPutAll: 'Calling ';
nextPutAll: aReceiver printString;
nextPutAll: '>>';
nextPutAll: compiledMethod selector printString;
newLine.
self printIndentation: stream.
stream nextPutAll: ' arguments: '; nextPutAll: arguments printString;
newLine.
! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:03:02'!
outputMethodExit: aReceiver result: result
|stream|
stream _ MessageTracer outputStream.
self printIndentation: stream.
stream nextPutAll: 'Returning from ';
nextPutAll: aReceiver printString;
nextPutAll: '>>';
nextPutAll: compiledMethod selector;
newLine.
self printIndentation: stream.
stream nextPutAll: ' returned: ';
nextPutAll: result printString;
newLine
! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:15:36'!
printIndentation: aStream
(self invocationLevel - 1) timesRepeat: [
aStream nextPutAll: ' |'].! !
!TracedMethodWrapper methodsFor: 'implementation' stamp: 'MM 7/29/2022 13:41:35'!
run: aSelector with: arguments in: aReceiver
"Main entry point"
| result |
enabled ifFalse: [^ compiledMethod valueWithReceiver: aReceiver arguments: arguments].
(#(onEntry around) includes: when) ifTrue: [
self outputMethodEntry: aReceiver arguments: arguments].
self increaseInvocationLevel .
[result _ compiledMethod valueWithReceiver: aReceiver arguments: arguments] ensure:
[self decreaseInvocationLevel].
(#(onExit around) includes: when) ifTrue: [
self outputMethodExit: aReceiver result: result].
^ result! !
!TracedMethodWrapper methodsFor: 'as yet unclassified' stamp: 'MM 11/5/2022 19:02:39'!
compiledMethod
^ compiledMethod! !
!TracedMethodWrapper methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:59:50'!
disable
enabled _ false! !
!TracedMethodWrapper methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 13:02:08'!
when: aSymbol
when _ aSymbol! !
!TracedMethodWrapper class methodsFor: 'as yet unclassified' stamp: 'MM 6/17/2022 12:03:49'!
on: aClass selector: selector
^ self new initialize: aClass selector: selector! !
!Browser methodsFor: '*MessageTracer' stamp: 'MM 11/5/2022 20:14:34'!
showTracedMessages
MessageTracerWindow open! !
!Browser methodsFor: '*MessageTracer' stamp: 'MM 11/5/2022 20:32:53'!
toggleMessageTracing
"Start or stop tracing current selected method"
| selectedMethod |
self selectedClassOrMetaClass ifNil: [ ^self].
selectedMethod := self selectedClassOrMetaClass >> self selectedMessageName.
MessageTracer toggleTrace: selectedMethod! !
!Behavior methodsFor: '*MessageTracer' stamp: 'MM 6/17/2022 13:35:02'!
trace: aSelector
MessageTracer trace: self selector: aSelector! !
!Behavior methodsFor: '*MessageTracer' stamp: 'MM 6/17/2022 13:40:56'!
untrace: aSelector
MessageTracer untrace: self selector: aSelector! !
More information about the Cuis-dev
mailing list