Login  Register

Fwd: 14827 ProtoObject>>pointersTo failing circular references

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options Options
Embed post
Permalink
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Fwd: 14827 ProtoObject>>pointersTo failing circular references

Ben Coman

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... 

cheers -ben

Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

Nicolai Hess
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 <[hidden email]>:

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... 

cheers -ben


Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

Nicolai Hess
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 <[hidden email]>:
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 <[hidden email]>:

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... 

cheers -ben



Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

Ben Coman
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 <[hidden email]> 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 <[hidden email]>:
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 <[hidden email]>:

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... 

cheers -ben




Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

Eliot Miranda-2


On Fri, Jan 30, 2015 at 6:32 AM, Ben Coman <[hidden email]> 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 <[hidden email]> 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 <[hidden email]>:
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 <[hidden email]>:

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... 

cheers -ben







--
best,
Eliot
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

stepharo



On Fri, Jan 30, 2015 at 6:32 AM, Ben Coman <[hidden email]> 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 <[hidden email]> 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 <[hidden email]>:
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 <[hidden email]>:

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... 

cheers -ben







--
best,
Eliot

Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: Fwd: 14827 ProtoObject>>pointersTo failing circular references

stepharo
In reply to this post by Ben Coman
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 <[hidden email]> 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 <[hidden email]>:
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 <[hidden email]>:

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... 

cheers -ben