Great!<div><br></div><div><div>So, say that I have an object z that I want to check all refs to:</div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><br></div><div>(define x (vector 1 2 3))</div>

</div><div><br></div></blockquote></div><div>well, and let's create two refs so the environment is completely set up:</div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>
(define y (lambda () z)) (define z (vector x))</div>
</div></blockquote><div><div><br></div><div>Scheme object references can be exported and imported using</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>(define int->scheme-object (c-lambda (unsigned-int64) scheme-object "___result = ___arg1;"))</div>

<div>(define scheme-object->int (c-lambda (scheme-object) unsigned-int64 "___result = ___arg1;"))</div></div><div><br></div></blockquote></div><div>so I do</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">

<div>(define r (scheme-object->int x)) r</div><div><br></div></blockquote></div><div>which shows that this vector has reference number 18446744072497743289 .</div><div><br></div><div>To the beginning of mem.c (row 20 and on) I add</div>

<div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>___WORD DEBUG_scanned_for_object_ref = -1;</div></div><div><br></div></blockquote></div><div>and in GDB I do</div><div><br>

</div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>set var DEBUG_scanned_for_object_ref=18446744072497743289 </div></div></blockquote><div><div><br></div>and then to <span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">validate_old_obj (</span>or mark_array) I add the equivalence check:</div>

<div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>      if (obj == DEBUG_scanned_for_object_ref) {</div><div>        fprintf(stderr,"The scanned for object reference %lu was referenced to by %lu .\n",DEBUG_scanned_for_object_ref,DEBUG_at_object);</div>

<div>      }</div></blockquote><div><br></div><div>Indeed it trigs as it should!<br></div><br></div><div><br></div><div>Now, question is just how to extract DEBUG_at_object .</div><div><br></div><div>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 . </div>

<div><br></div><div><br></div><div>How do I get the ___SCMOBJ that container_body will have after the garbage collection is performed?</div><div><br></div><div>(Or alternatively, how do I cancel the garbage collection, and get the ___SCMOBJ for container_body in its present location)</div>

<div><br></div><br><div class="gmail_quote">2013/6/18 Marc Feeley <span dir="ltr"><<a href="mailto:feeley@iro.umontreal.ca" target="_blank">feeley@iro.umontreal.ca</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

First you have to<br>
<br>
./configure --enable-debug<br>
<br>
this will enable the code in the GC that does consistency checking and also maintains some auxiliairy information that is useful.<br>
<br>
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.<br>


<br>
   if (obj == looking_for) printf("found!\n");<br>
<br>
*All* live references will be passed to this function (if your runtime debug options are -:d1 or above).<br>
<br>
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<br>


<br>
#define IN_OBJECT       0<br>
#define IN_REGISTER     1<br>
#define IN_GLOBAL_VAR   2<br>
#define IN_WILL_LIST    3<br>
#define IN_CONTINUATION 4<br>
#define IN_RC           5<br>
<br>
The variable container_body is only valid when reference_location == IN_OBJECT.<br>
<span class="HOEnZb"><font color="#888888"><br>
Marc<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 2013-06-18, at 9:30 AM, Mikael <<a href="mailto:mikael.rcv@gmail.com">mikael.rcv@gmail.com</a>> wrote:<br>
<br>
><br>
><br>
> 2013/6/18 Marc Feeley <<a href="mailto:feeley@iro.umontreal.ca">feeley@iro.umontreal.ca</a>><br>
><br>
> It is not in Gambit, but it would be easy to modify the GC to do this.<br>
><br>
> Right!<br>
><br>
> Three q:s on how to do this -<br>
><br>
><br>
><br>
> I'm reading mem.c right now and it looks like the mark_array() procedure would be the place to put this check in.<br>
><br>
> The GC copy phase is about changing every object reference to a new one.<br>
> So, if during the mark phase I'd print out the ___SCMOBJ of the referencing object, that would change during the GC.<br>
><br>
>  * 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??<br>
><br>
>  * 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?<br>
><br>
><br>
>  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.<br>


><br>
> 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:<br>


><br>
><br>
>   while (n > 0)<br>
>     {<br>
>       ___WORD obj = *start;<br>
><br>
>       [Here - row 2100]<br>
><br>
>       if (___MEM_ALLOCATED(obj))<br>
>         {<br>
>           ___WORD *body;<br>
>           ___WORD head;<br>
>           int head_typ;<br>
>           int subtype;<br>
><br>
><br>
><br>
>  * 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?<br>
><br>
>  So a leak is possible if there's a missing reference count "decrement" in the code.<br>
><br>
> 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 -<br>
><br>
> ##serial-number-to-object-table is growing up to heap overflow!<br>
><br>
><br>
> Marc<br>
><br>
><br>
><br>
> Best regards,<br>
> Mikael<br>
><br>
<br>
</div></div></blockquote></div><br></div>