Finding pointers via heap walking and contexts

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Finding pointers via heap walking and contexts

Igor Stasenko
 
Hello,

i tried to implement a simple algorithm to find nearest common roots for some object(s)..
see the attached code.

The problem i discovered that the last assertion of my test fails:
=====
testArrayShouldBeRootOfItsElements

    | obj1 obj2 array arrayToTest roots |
   
    obj1 := 'ObjectA' copy.
    obj2 := 'ObjectB' copy.
   
    array := {  obj1. obj2 }.
    arrayToTest := { obj1. obj2 }.
   
    roots := CommonRootsFinder new findCommonRootsOf:  arrayToTest.
   
    self assert: (roots identityIncludes: array).
    self assert: (roots identityIncludes: arrayToTest) not.
    self assert: (roots identityIncludes: thisContext).  "- sometimes works , sometimes not "
========

but, when i restart the method in debugger and step down through it, assertion DOES NOT fails.
This means that memory scan does not reveals this context as it should be.

(maybe because it stops at the object which located before location of thisContext)?

any suggestions/comments/ideas , how to make sure that assert will never fail?

--
Best regards,
Igor Stasenko.

CommonRootsFinder.st (7K) Download Attachment
CommonRootsFinderTest.st (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Finding pointers via heap walking and contexts

Eliot Miranda-2
 



On Thu, Aug 29, 2013 at 8:54 AM, Igor Stasenko <[hidden email]> wrote:
 
Hello,

i tried to implement a simple algorithm to find nearest common roots for some object(s)..
see the attached code.

The problem i discovered that the last assertion of my test fails:
=====
testArrayShouldBeRootOfItsElements

    | obj1 obj2 array arrayToTest roots |
   
    obj1 := 'ObjectA' copy.
    obj2 := 'ObjectB' copy.
   
    array := {  obj1. obj2 }.
    arrayToTest := { obj1. obj2 }.
   
    roots := CommonRootsFinder new findCommonRootsOf:  arrayToTest.
   
    self assert: (roots identityIncludes: array).
    self assert: (roots identityIncludes: arrayToTest) not.
    self assert: (roots identityIncludes: thisContext).  "- sometimes works , sometimes not "
========

but, when i restart the method in debugger and step down through it, assertion DOES NOT fails.
This means that memory scan does not reveals this context as it should be.

(maybe because it stops at the object which located before location of thisContext)?

That would make sense.  For debugging, why don't you record the objects visited in an OrderedCollection, and then you can look at what order the pointer finder found them.
 

any suggestions/comments/ideas , how to make sure that assert will never fail?

Doesn't that depend on how you've implemented CommonRootsFinder?


--
Best regards,
Igor Stasenko.




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

Re: Finding pointers via heap walking and contexts

Igor Stasenko
 



On 29 August 2013 18:34, Eliot Miranda <[hidden email]> wrote:
 



On Thu, Aug 29, 2013 at 8:54 AM, Igor Stasenko <[hidden email]> wrote:
 
Hello,

i tried to implement a simple algorithm to find nearest common roots for some object(s)..
see the attached code.

The problem i discovered that the last assertion of my test fails:
=====
testArrayShouldBeRootOfItsElements

    | obj1 obj2 array arrayToTest roots |
   
    obj1 := 'ObjectA' copy.
    obj2 := 'ObjectB' copy.
   
    array := {  obj1. obj2 }.
    arrayToTest := { obj1. obj2 }.
   
    roots := CommonRootsFinder new findCommonRootsOf:  arrayToTest.
   
    self assert: (roots identityIncludes: array).
    self assert: (roots identityIncludes: arrayToTest) not.
    self assert: (roots identityIncludes: thisContext).  "- sometimes works , sometimes not "
========

but, when i restart the method in debugger and step down through it, assertion DOES NOT fails.
This means that memory scan does not reveals this context as it should be.

(maybe because it stops at the object which located before location of thisContext)?

That would make sense.  For debugging, why don't you record the objects visited in an OrderedCollection, and then you can look at what order the pointer finder found them.
 

well, if you look at algorithm:

    pointers := IdentitySet new.
    object := self someObject.
    [ object == pointers ] whileFalse: [
        1 to: objects size do: [ :i | ((object pointsTo: (objects at: i)) and: [ (object pointsOnlyWeaklyTo: (objects at: i)) not]) ifTrue: [ pointers add: object ]  ].
        object := object nextObject ].

since the 'pointers' is the last object created on heap, and the subject context
must exist before entering this method, it should eventually find it..
but as it appears it doesn't..

what i thinking, that maybe i should change the stop condition to
[ object == 0 ]
(which primitive returns when there is no more object on heap),
like that i can be sure that i will visit every heap-allocated object..
But that is tricky because then loop may never stop if there is new object(s) created (like in #add: ) in loop body..   :(




any suggestions/comments/ideas , how to make sure that assert will never fail?

Doesn't that depend on how you've implemented CommonRootsFinder?


--
Best regards,
Igor Stasenko.




--
best,
Eliot




--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: Finding pointers via heap walking and contexts

Igor Stasenko
 
ahh.. idioto, of course it can't find:

because i rejecting it:

(pointers reject: [ :ptr |
        (ptr isContext and: [ ptr callChainAnySatisfy: [ :ctx | ctx == bottomContext ] ]) or: [ (exceptions identityIncludes: ptr) or: [ptr==exceptions] ]]) asArray

while i wanted to reject all contexts is on top of bottomContext or the bottomContext itself,
but not below it,
but this condition actually means: 'reject any context if it on same stack as bottomContext'

:)




On 29 August 2013 19:40, Igor Stasenko <[hidden email]> wrote:



On 29 August 2013 18:34, Eliot Miranda <[hidden email]> wrote:
 



On Thu, Aug 29, 2013 at 8:54 AM, Igor Stasenko <[hidden email]> wrote:
 
Hello,

i tried to implement a simple algorithm to find nearest common roots for some object(s)..
see the attached code.

The problem i discovered that the last assertion of my test fails:
=====
testArrayShouldBeRootOfItsElements

    | obj1 obj2 array arrayToTest roots |
   
    obj1 := 'ObjectA' copy.
    obj2 := 'ObjectB' copy.
   
    array := {  obj1. obj2 }.
    arrayToTest := { obj1. obj2 }.
   
    roots := CommonRootsFinder new findCommonRootsOf:  arrayToTest.
   
    self assert: (roots identityIncludes: array).
    self assert: (roots identityIncludes: arrayToTest) not.
    self assert: (roots identityIncludes: thisContext).  "- sometimes works , sometimes not "
========

but, when i restart the method in debugger and step down through it, assertion DOES NOT fails.
This means that memory scan does not reveals this context as it should be.

(maybe because it stops at the object which located before location of thisContext)?

That would make sense.  For debugging, why don't you record the objects visited in an OrderedCollection, and then you can look at what order the pointer finder found them.
 

well, if you look at algorithm:

    pointers := IdentitySet new.
    object := self someObject.
    [ object == pointers ] whileFalse: [
        1 to: objects size do: [ :i | ((object pointsTo: (objects at: i)) and: [ (object pointsOnlyWeaklyTo: (objects at: i)) not]) ifTrue: [ pointers add: object ]  ].
        object := object nextObject ].

since the 'pointers' is the last object created on heap, and the subject context
must exist before entering this method, it should eventually find it..
but as it appears it doesn't..

what i thinking, that maybe i should change the stop condition to
[ object == 0 ]
(which primitive returns when there is no more object on heap),
like that i can be sure that i will visit every heap-allocated object..
But that is tricky because then loop may never stop if there is new object(s) created (like in #add: ) in loop body..   :(




any suggestions/comments/ideas , how to make sure that assert will never fail?

Doesn't that depend on how you've implemented CommonRootsFinder?


--
Best regards,
Igor Stasenko.




--
best,
Eliot




--
Best regards,
Igor Stasenko.



--
Best regards,
Igor Stasenko.