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 <[email protected] <mailto:[email protected]>> 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 <[email protected]
    <mailto:[email protected]>>:

        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 <[email protected]
        <mailto:[email protected]>>:


            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





Reply via email to