[squeak-dev] Re: Cannot debug from Process browser

Chris Muller asqueaker at gmail.com
Wed Dec 5 19:46:10 UTC 2012


Printing this before pressing Command+d on the Process browser:

  Link allSubInstances count: [ : e | e nextLink==e]

reports 0.

AFTER I press Command+d, I have to press Command+. to interrupt the
infinite recursion, which exposes the debugger which is trying to open
the debugger on the process I selected (see below for the stack).  NOW

  Link allSubInstances count: [ : e | e nextLink==e]

reports 1, and the one instance is the Process I was trying to debug.

So, I overrode Process>>#nextLink: setter to guard against setting it
to himself and repeating the test.  The guard was never hit, but the
same condition ('nextLink' referring to itself) still formed.  This is
impossible since that's the only writer of that variable unless the VM
or other low-level mechanism is setting the Process' nextLink.

================
Here's the stack of trying to invoke 'debug' from the Process Browser.
 A MethodContext is just trying to render its printString as part of
Debugger operations but it can't because of the cycle.  Any ideas?

5 December 2012 1:34:25.32 pm

VM: unix - Smalltalk
Image: Squeak4.3 [latest update: #12292]

SecurityManager state:
Restricted: false
FileAccess: true
SocketAccess: true
Working Dir /home/cmm/Chris/development/Squeak
Trusted Dir /home/cmm/Chris/development/Squeak/secure
Untrusted Dir /home/cmm/Chris/development/Squeak/My Squeak

[] in Semaphore(LinkedList)>>size
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
tally: a Process in [] in DelayWaitTimeout>>wait
each: #(25729379)
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

Semaphore(LinkedList)>>do:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
aBlock: [closure] in Semaphore(LinkedList)>>size
aLink: a Process in [] in DelayWaitTimeout>>wait
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

Semaphore(LinkedList)>>size
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
tally: #(25729379)
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

Semaphore(SequenceableCollection)>>do:separatedBy:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
elementBlock: [closure] in Semaphore(Collection)>>printElementsOn:
separatorBlock: [closure] in Semaphore(Collection)>>printElementsOn:
index: nil
indexLimiT: nil
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

Semaphore(Collection)>>printElementsOn:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
aStream: a LimitedWriteStream 'a Semaphore('
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

Semaphore(Collection)>>printOn:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
aStream: a LimitedWriteStream 'a Semaphore('
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

[] in Semaphore(Object)>>printStringLimitedTo:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
<<error during printing>
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

String class(SequenceableCollection class)>>streamContents:limitedTo:
Receiver: String
Arguments and temporary variables:
blockWithArg: [closure] in Semaphore(Object)>>printStringLimitedTo:
sizeLimit: 63
stream: a LimitedWriteStream 'a Semaphore('
Receiver's instance variables:
superclass: ArrayedCollection
methodDict: a MethodDictionary(size 286)
format: 2
instanceVariables: nil
organization: ('accessing' byteAt: byteAt:put: byteSize
do:toFieldNumber: findA...etc...
subclasses: {ByteString . WideString . Symbol}
name: #String
classPool: a Dictionary(#AsciiOrder->#[0 1 2 3 4 5 6 7 8 9 10 11 12 13
14 15 16...etc...
sharedPools: nil
environment: Smalltalk globals "a SystemDictionary with lots of globals"
category: #'Collections-Strings'

Semaphore(Object)>>printStringLimitedTo:
Receiver: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
Arguments and temporary variables:
limit: 63
limitedString: nil
Receiver's instance variables:
firstLink: a Process in [] in DelayWaitTimeout>>wait
lastLink: a Process in [] in DelayWaitTimeout>>wait
excessSignals: 0

[] in DelayWaitTimeout(Object)>>longPrintOn:limitedTo:indent:
Receiver: a DelayWaitTimeout(172748169 msecs; 172583302 msecs remaining)
Arguments and temporary variables:
aStream: 'delaySemaphore'
sizeLimit: 3
indent: MultiByteFileStream:
'/home/cmm/Chris/development/Squeak/SqueakDebug.lo...etc...
title: 80
index: 2
Receiver's instance variables:
delayDuration: 172748169
resumptionTime: 172953821
delaySemaphore: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
beingWaitedOn: true
process: a Process in [] in DelayWaitTimeout>>wait
expired: false

Array(SequenceableCollection)>>withIndexDo:
Receiver: #('delayDuration' 'resumptionTime' 'delaySemaphore'
'beingWaitedOn' 'process' 'expired')
Arguments and temporary variables:
elementAndIndexBlock: [closure] in
DelayWaitTimeout(Object)>>longPrintOn:limite...etc...
index: 3
indexLimiT: 6
Receiver's instance variables:
#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWaitedOn'
'process' 'expired')

Array(SequenceableCollection)>>doWithIndex:
Receiver: #('delayDuration' 'resumptionTime' 'delaySemaphore'
'beingWaitedOn' 'process' 'expired')
Arguments and temporary variables:
elementAndIndexBlock: [closure] in
DelayWaitTimeout(Object)>>longPrintOn:limite...etc...
Receiver's instance variables:
#('delayDuration' 'resumptionTime' 'delaySemaphore' 'beingWaitedOn'
'process' 'expired')

DelayWaitTimeout(Object)>>longPrintOn:limitedTo:indent:
Receiver: a DelayWaitTimeout(172748169 msecs; 172583298 msecs remaining)
Arguments and temporary variables:
aStream: MultiByteFileStream:
'/home/cmm/Chris/development/Squeak/SqueakDebug.l...etc...
sizeLimit: 80
indent: 2
Receiver's instance variables:
delayDuration: 172748169
resumptionTime: 172953821
delaySemaphore: a Semaphore(a Process in [] in DelayWaitTimeout>>wait)
beingWaitedOn: true
process: a Process in [] in DelayWaitTimeout>>wait
expired: false

[] in MethodContext>>printDetails:
Receiver: [] in DelayWaitTimeout>>wait
Arguments and temporary variables:
<<error during printing>
Receiver's instance variables:
sender: BlockClosure>>ensure:
pc: 44
stackp: 1
method: (DelayWaitTimeout>>#wait "a CompiledMethod(2835)")
closureOrNil: [closure] in DelayWaitTimeout>>wait
receiver: a DelayWaitTimeout(172748169 msecs; 172583298 msecs remaining)

BlockClosure>>on:do:
Receiver: [closure] in MethodContext>>printDetails:
Arguments and temporary variables:
exception: Error
handlerAction: [closure] in BlockClosure>>ifError:
handlerActive: true
Receiver's instance variables:
outerContext: MethodContext>>printDetails:
startpc: 197
numArgs: 0

BlockClosure>>ifError:
Receiver: [closure] in MethodContext>>printDetails:
Arguments and temporary variables:
errorHandlerBlock: [closure] in MethodContext>>printDetails:
Receiver's instance variables:
outerContext: MethodContext>>printDetails:
startpc: 197
numArgs: 0

MethodContext>>printDetails:
Receiver: [] in DelayWaitTimeout>>wait
Arguments and temporary variables:
strm: MultiByteFileStream:
'/home/cmm/Chris/development/Squeak/SqueakDebug.log'...etc...
pe: '<<error during printing>>'
str: 'x'
pos: 544
Receiver's instance variables:
sender: BlockClosure>>ensure:
pc: 44
stackp: 1
method: (DelayWaitTimeout>>#wait "a CompiledMethod(2835)")
closureOrNil: [closure] in DelayWaitTimeout>>wait
receiver: a DelayWaitTimeout(172748169 msecs; 172583294 msecs remaining)

MethodContext(ContextPart)>>errorReportOn:
Receiver: [] in DelayWaitTimeout>>wait
Arguments and temporary variables:
strm: MultiByteFileStream:
'/home/cmm/Chris/development/Squeak/SqueakDebug.log'...etc...
cnt: 1
aContext: [] in DelayWaitTimeout>>wait
startPos: 370
Receiver's instance variables:
sender: BlockClosure>>ensure:
pc: 44
stackp: 1
method: (DelayWaitTimeout>>#wait "a CompiledMethod(2835)")
closureOrNil: [closure] in DelayWaitTimeout>>wait
receiver: a DelayWaitTimeout(172748169 msecs; 172583286 msecs remaining)

SmalltalkImage>>logError:inContext:to:
Receiver: Smalltalk
Arguments and temporary variables:
errMsg: 'Interrupted from the Process Browser'
aContext: [] in DelayWaitTimeout>>wait
aFilename: 'SqueakDebug.log'
ff: MultiByteFileStream: '/home/cmm/Chris/development/Squeak/SqueakDebug.log'
Receiver's instance variables:
globals: Smalltalk globals "a SystemDictionary with lots of globals"


--- The full stack ---
[] in Semaphore(LinkedList)>>size
Semaphore(LinkedList)>>do:
Semaphore(LinkedList)>>size
Semaphore(SequenceableCollection)>>do:separatedBy:
Semaphore(Collection)>>printElementsOn:
Semaphore(Collection)>>printOn:
[] in Semaphore(Object)>>printStringLimitedTo:
String class(SequenceableCollection class)>>streamContents:limitedTo:
Semaphore(Object)>>printStringLimitedTo:
[] in DelayWaitTimeout(Object)>>longPrintOn:limitedTo:indent:
Array(SequenceableCollection)>>withIndexDo:
Array(SequenceableCollection)>>doWithIndex:
DelayWaitTimeout(Object)>>longPrintOn:limitedTo:indent:
[] in MethodContext>>printDetails:
BlockClosure>>on:do:
BlockClosure>>ifError:
MethodContext>>printDetails:
MethodContext(ContextPart)>>errorReportOn:
SmalltalkImage>>logError:inContext:to:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SmalltalkImage>>logSqueakError:inContext:
[] in Debugger class>>morphicOpenOn:context:label:contents:fullView:
BlockClosure>>on:do:
Debugger class>>morphicOpenOn:context:label:contents:fullView:
MorphicProject(Project)>>dispatchTo:addPrefixAndSend:withArguments:
Debugger class>>openOn:context:label:contents:fullView:
StandardToolSet class>>debug:context:label:contents:fullView:
ToolSet class>>debug:context:label:contents:fullView:
Process>>debug:title:full:
Process>>debugWithTitle:
ProcessBrowser class>>debugProcess:
ProcessBrowser>>debugProcess
ProcessBrowser>>processListKey:from:
PluggableListMorphPlus(PluggableListMorph)>>modifierKeyPressed:
PluggableListMorphPlus(PluggableListMorph)>>keyStroke:
PluggableListMorphPlus(Morph)>>handleKeystroke:
KeyboardEvent>>sentTo:
PluggableListMorphPlus(Morph)>>handleEvent:
PluggableListMorphPlus(Morph)>>handleFocusEvent:
[] in HandMorph>>sendFocusEvent:to:clear:
BlockClosure>>on:do:
PasteUpMorph>>becomeActiveDuring:
HandMorph>>sendFocusEvent:to:clear:
HandMorph>>sendEvent:focus:clear:
HandMorph>>sendKeyboardEvent:
HandMorph>>handleEvent:
HandMorph>>processEvents
[] in WorldState>>doOneCycleNowFor:
Array(SequenceableCollection)>>do:
WorldState>>handsDo:
WorldState>>doOneCycleNowFor:
WorldState>>doOneCycleFor:
PasteUpMorph>>doOneCycle
[] in Project class>>spawnNewProcess
[] in BlockClosure>>newProcess



On Wed, Dec 5, 2012 at 11:33 AM, Chris Muller <asqueaker at gmail.com> wrote:
>
> A few times lately I have noticed I can no longer open a debugger from the Process browser (via Command+d).  As soon as I select it the image locks up.
>
> If I break in with Command+. right away I was able to do some minimal tracing.  It appears the Process instance I want to debug; his #nextLink is himself. This results an endless recursion when his printing method simply tries to ask his #size.
>
> Incidentally, the Process I wanted to debug was simply waiting on a Semaphore of a network Socket, not actually doing any processing when I tried to debug it, and I can reproduce this problem every time.
>
> I *know* I used to be able to debug these; anyone have any ideas what could be wrong now?
>
> thanks..


More information about the Squeak-dev mailing list