Fwd: 14827 ProtoObject>>pointersTo failing circular references
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo. The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX. On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image... testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect. OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs. I've logged... https://pharo.fogbugz.com/default.asp?14827 cheers -ben
Hi Ben, i don't know exactly what is happening here, but (size vs. inpsect) testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5 works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements. 2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
Quick and Dirty, replace Array>>#printOn: with printOn: aStream self class = Array ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo asString works 2015-01-30 14:15 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
Hi Ben,
i don't know exactly what is happening here, but (size vs. inpsect)
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5
works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
Yes. I just got back to looking at it and noticed the culprit was printString. Now #printString --> #printStringLimitedTo: --> #streamContents:limitedTo: which uses LimitedWriteStream that should protect against such recursion. However Array>>printOn: is... self shouldBePrintedAsLiteral ifTrue: [self printAsLiteralFormOn: aStream. ^ self]. self isSelfEvaluating ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream where #shouldBePrintedAsLiteral and #isSelfEvaluating recursively call themselves - bypassing the protection of LimitedWriteStream. As an aside, Array>>shouldBePrintedAsLiteral seems identical to Array>>isLiteral -- so is it redundant and the former be deprecated? Now I don't quite follow the semantics of #isLiteral and #isSelfEvaluating for Arrays. a := #( 1 2 { 3 . 4 } 5). a isLiteral. "true" a isSelfEvaluating. "true" b := { 1 . 2 . #( 3 4 ) . 5 }. b isLiteral. "true" b isSelfEvaluating. "true" So can someone provide an example for an Array where #isLiteral or #isSelfEvaluating are false ? Otherwise it seems it will always take the first condition of Array>>printOn: . cheers -ben On Fri, Jan 30, 2015 at 9:23 PM, Nicolai Hess <nicolaihess@web.de> wrote:
Quick and Dirty, replace Array>>#printOn: with
printOn: aStream self class = Array ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo asString
works
2015-01-30 14:15 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
Hi Ben,
i don't know exactly what is happening here, but (size vs. inpsect)
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5
works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
On Fri, Jan 30, 2015 at 6:32 AM, Ben Coman <btc@openinworld.com> wrote:
Yes. I just got back to looking at it and noticed the culprit was printString. Now #printString --> #printStringLimitedTo: --> #streamContents:limitedTo: which uses LimitedWriteStream that should protect against such recursion.
However Array>>printOn: is...
self shouldBePrintedAsLiteral ifTrue: [self printAsLiteralFormOn: aStream. ^ self]. self isSelfEvaluating ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
where #shouldBePrintedAsLiteral and #isSelfEvaluating recursively call themselves - bypassing the protection of LimitedWriteStream.
As an aside, Array>>shouldBePrintedAsLiteral seems identical to Array>>isLiteral -- so is it redundant and the former be deprecated?
Now I don't quite follow the semantics of #isLiteral and #isSelfEvaluating for Arrays.
a := #( 1 2 { 3 . 4 } 5). a isLiteral. "true" a isSelfEvaluating. "true"
b := { 1 . 2 . #( 3 4 ) . 5 }. b isLiteral. "true" b isSelfEvaluating. "true"
So can someone provide an example for an Array where #isLiteral or #isSelfEvaluating are false ? Otherwise it seems it will always take the first condition of Array>>printOn: .
An Array that contains anything that isn't literal. e.g. {1@2} {1@2} isLiteral => false {{1@2} size. #(1@2) size} => #(1 3)
cheers -ben
On Fri, Jan 30, 2015 at 9:23 PM, Nicolai Hess <nicolaihess@web.de> wrote:
Quick and Dirty, replace Array>>#printOn: with
printOn: aStream self class = Array ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo asString
works
2015-01-30 14:15 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
Hi Ben,
i don't know exactly what is happening here, but (size vs. inpsect)
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5
works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
-- best, Eliot
On Fri, Jan 30, 2015 at 6:32 AM, Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>> wrote:
Yes. I just got back to looking at it and noticed the culprit was printString. Now #printString --> #printStringLimitedTo: --> #streamContents:limitedTo: which uses LimitedWriteStream that should protect against such recursion.
However Array>>printOn: is...
self shouldBePrintedAsLiteral ifTrue: [self printAsLiteralFormOn: aStream. ^ self]. self isSelfEvaluating ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
where #shouldBePrintedAsLiteral and #isSelfEvaluating recursively call themselves - bypassing the protection of LimitedWriteStream.
As an aside, Array>>shouldBePrintedAsLiteral seems identical to Array>>isLiteral -- so is it redundant and the former be deprecated?
Now I don't quite follow the semantics of #isLiteral and #isSelfEvaluating for Arrays.
a := #( 1 2 { 3 . 4 } 5). a isLiteral. "true" a isSelfEvaluating. "true"
b := { 1 . 2 . #( 3 4 ) . 5 }. b isLiteral. "true" b isSelfEvaluating. "true"
So can someone provide an example for an Array where #isLiteral or #isSelfEvaluating are false ? Otherwise it seems it will always take the first condition of Array>>printOn: .
An Array that contains anything that isn't literal. e.g.
{1@2}
{1@2} isLiteral => false
{{1@2} size. #(1@2) size} => #(1 3)
and now normally isSelfEvaluating should return true because {{1@2} . #(1@2) } isSelfEvaluating -> true because 1@2 while not being a literal is still a cool object whose representation represents it fully. In pharo {(1@2). (1 @ 2)} printString ->{(1@2). (1@2)} and not #(....#
cheers -ben
On Fri, Jan 30, 2015 at 9:23 PM, Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>> wrote:
Quick and Dirty, replace Array>>#printOn: with
printOn: aStream self class = Array ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo asString
works
2015-01-30 14:15 GMT+01:00 Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>>:
Hi Ben,
i don't know exactly what is happening here, but (size vs. inpsect)
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5
works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
-- best, Eliot
So you found a bug :) Le 30/1/15 15:32, Ben Coman a écrit :
Yes. I just got back to looking at it and noticed the culprit was printString. Now #printString --> #printStringLimitedTo: --> #streamContents:limitedTo: which uses LimitedWriteStream that should protect against such recursion.
However Array>>printOn: is...
self shouldBePrintedAsLiteral ifTrue: [self printAsLiteralFormOn: aStream. ^ self]. self isSelfEvaluating ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
where #shouldBePrintedAsLiteral and #isSelfEvaluating recursively call themselves - bypassing the protection of LimitedWriteStream.
As an aside, Array>>shouldBePrintedAsLiteral seems identical to Array>>isLiteral -- so is it redundant and the former be deprecated?
Now I don't quite follow the semantics of #isLiteral and #isSelfEvaluating for Arrays.
a := #( 1 2 { 3 . 4 } 5). a isLiteral. "true" a isSelfEvaluating. "true"
b := { 1 . 2 . #( 3 4 ) . 5 }. b isLiteral. "true" b isSelfEvaluating. "true"
So can someone provide an example for an Array where #isLiteral or #isSelfEvaluating are false ? Otherwise it seems it will always take the first condition of Array>>printOn: .
cheers -ben
On Fri, Jan 30, 2015 at 9:23 PM, Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>> wrote:
Quick and Dirty, replace Array>>#printOn: with
printOn: aStream self class = Array ifTrue: [self printAsSelfEvaluatingFormOn: aStream. ^ self]. super printOn: aStream
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo asString
works
2015-01-30 14:15 GMT+01:00 Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>>:
Hi Ben,
i don't know exactly what is happening here, but (size vs. inpsect)
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo size -> 5
works. So, the problem is not in #pointersTo but inspecting the result array has one or more recursive self calls to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>>:
I am revisiting my PointerDetective tool, which relies heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is currently locking & crashing the image due to #pointersTo being unable to handle the circular reference. This "must" have been working on Windows at least around August 2014, but I've been unable to reproduce a working case since my Windows laptop died and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the following crashes the image...
testObject := 'TEST'. ref1 := { testObject. nil }. ref2 := { ref1 }. ref3 := { ref2 }. ref1 at: 2 put: ref3. "note the reference loop this creates" testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB to >500MB in a few seconds, then usually the image crashes, but sometimes just hangs.
I've logged... https://pharo.fogbugz.com/default.asp?14827
cheers -ben
participants (4)
-
Ben Coman -
Eliot Miranda -
Nicolai Hess -
stepharo