[gambit-list] Any procedure/debug way to see what objects reference an object?

Mikael mikael.rcv at gmail.com
Tue Jun 18 13:28:25 EDT 2013


Great!

So, say that I have an object z that I want to check all refs to:


(define x (vector 1 2 3))

well, and let's create two refs so the environment is completely set up:

(define y (lambda () z)) (define z (vector x))


Scheme object references can be exported and imported using

(define int->scheme-object (c-lambda (unsigned-int64) scheme-object
"___result = ___arg1;"))
(define scheme-object->int (c-lambda (scheme-object) unsigned-int64
"___result = ___arg1;"))

so I do

(define r (scheme-object->int x)) r

which shows that this vector has reference number 18446744072497743289 .

To the beginning of mem.c (row 20 and on) I add

___WORD DEBUG_scanned_for_object_ref = -1;

and in GDB I do

set var DEBUG_scanned_for_object_ref=18446744072497743289


and then to validate_old_obj (or mark_array) I add the equivalence check:

      if (obj == DEBUG_scanned_for_object_ref) {
        fprintf(stderr,"The scanned for object reference %lu was referenced
to by %lu .\n",DEBUG_scanned_for_object_ref,DEBUG_at_object);
      }


Indeed it trigs as it should!


Now, question is just how to extract DEBUG_at_object .

So, presuming reference_location == IN_OBJECT , we have the content of the
object containing the reference in container_body , and we can print some
debug info about this object using explain_problem .


How do I get the ___SCMOBJ that container_body will have after the garbage
collection is performed?

(Or alternatively, how do I cancel the garbage collection, and get the
___SCMOBJ for container_body in its present location)


2013/6/18 Marc Feeley <feeley at iro.umontreal.ca>

> First you have to
>
> ./configure --enable-debug
>
> this will enable the code in the GC that does consistency checking and
> also maintains some auxiliairy information that is useful.
>
> The function mark_array is the only function doing the marking.  If the
> debug level is >= 1 it will call the function validate_old_obj(obj) to
> check that the object reference is indeed pointing to the old semispace.
>  This is a convenient place to do something with the reference, such as
> checking if it is the one you are looking for, i.e.
>
>    if (obj == looking_for) printf("found!\n");
>
> *All* live references will be passed to this function (if your runtime
> debug options are -:d1 or above).
>
> In validate_old_obj you can use the variables reference_location and
> container_body to determine where the reference was found.  Check the
> definition of the function explain_problem to see how to use this
> information.  The reference_location can be
>
> #define IN_OBJECT       0
> #define IN_REGISTER     1
> #define IN_GLOBAL_VAR   2
> #define IN_WILL_LIST    3
> #define IN_CONTINUATION 4
> #define IN_RC           5
>
> The variable container_body is only valid when reference_location ==
> IN_OBJECT.
>
> Marc
>
>
>
> On 2013-06-18, at 9:30 AM, Mikael <mikael.rcv at gmail.com> wrote:
>
> >
> >
> > 2013/6/18 Marc Feeley <feeley at iro.umontreal.ca>
> >
> > It is not in Gambit, but it would be easy to modify the GC to do this.
> >
> > Right!
> >
> > Three q:s on how to do this -
> >
> >
> >
> > I'm reading mem.c right now and it looks like the mark_array() procedure
> would be the place to put this check in.
> >
> > The GC copy phase is about changing every object reference to a new one.
> > So, if during the mark phase I'd print out the ___SCMOBJ of the
> referencing object, that would change during the GC.
> >
> >  * Where in mem.c is the copy phase implemented? I can't find it or any
> reference to it in ___garbage_collect , that would not be the section "Move
> the stack", would it??
> >
> >  * Could I safely run ___garbage_collect up to where the copy begins and
> then just return() it right there as to keep the validity of the references
> of the referencing objects I found?
> >
> >
> >  By the way, your proposed API is not quite right because the references
> can be in non Scheme objects (for example global variables, a stack frame,
> a C allocated object).  Also, it could be that the object is a ___STILL
> object that has a non-zero reference count.
> >
> > That would be cool - the objects I'm looking to track references of are
> deep in the Scheme logics only and unrelated with any FFI or other special
> object management. So I'd guess the place to check for the object would be
> in the loop in mark_array:
> >
> >
> >   while (n > 0)
> >     {
> >       ___WORD obj = *start;
> >
> >       [Here - row 2100]
> >
> >       if (___MEM_ALLOCATED(obj))
> >         {
> >           ___WORD *body;
> >           ___WORD head;
> >           int head_typ;
> >           int subtype;
> >
> >
> >
> >  * Last, in mark_array, can I easily detect the object reference to the
> object whose content is being marked here, or do I need to add this as
> another argument to mark_array?
> >
> >  So a leak is possible if there's a missing reference count "decrement"
> in the code.
> >
> > Ah right - the nature of this memory leak is not such. The only ___STILL
> variables I have are u8vectors , and the issue I have is that some
> procedures and vectors fill up the heap -
> >
> > ##serial-number-to-object-table is growing up to heap overflow!
> >
> >
> > Marc
> >
> >
> >
> > Best regards,
> > Mikael
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130618/dd022a1f/attachment.htm>


More information about the Gambit-list mailing list