<div dir="ltr">Hi Guille, Hi Pablo (and welcome),<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 17, 2016 at 8:37 AM, Guille Polito <span dir="ltr">&lt;<a href="mailto:guillermopolito@gmail.com" target="_blank">guillermopolito@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi Eliot, list<br>
<br>
I&#39;m working here with Pablo (Tesone) on moving forward the Ephemeron implementation. We first installed Eliot&#39;s changeset, added a #mourn method and an EphemeronDictionary collection, and then started testing something like this:<br>
<br>
f := ObjectFinalizer receiver: &#39;Hello&#39; selector: #logCr.<br>
d := EphemeronDictionary new.<br>
<br>
d at: f put: f.<br>
<br>
f := nil.<br>
Smalltalk garbageCollect.<br></blockquote><div><br></div><div>So this looks like something simulate able.  Are you able to use the simulator?  If not, why not?  </div><div><br></div><div>When debugging the VM there are two main levels of support, one is the simulator where there is maximum support for debugging:</div><div>- asserts on all the time</div><div>- arbitrary breakpoints</div><div>- attempting every GC in a copy of the heap before doing the real GC so that bugs in the GC can be investigated without needing to construct a reproducible case after a crash</div><div>- the Smalltalk environment to inspect and browse</div><div><br></div><div>The next level is the assert and debug VMs.  If you look in the build directories on the Cog svn branch you&#39;ll see that all of them build three VMs, a production VM with maximum optimisation and asserts excluded, an assert VM with -O1 and asserts enabled, and a debug VM with -O0 and asserts enabled.  So if you either don&#39;t see the bug in the simulator, or the simulator is too slow for the case being examined, or if the bug doesn&#39;t show up in the simulator (the worst of all worlds), build both assert and debug VMs and run with the assert VM first.</div><div><br></div><div>Note that there is a heap leak checker which can be enabled both in the simulator and the assert and debug VMs.  See the checkForLeaks method and the -leakcheck argument.</div><div><br></div><div>Without the simulator or the assert and debug VMs you are flying blind.  It is /really/ productive to use the simulator for debugging, provided the bug is reproducible within a short amount of time, as for example your case is above.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
However, as soon as we garbage collect twice, we have a VM crash. We started debugging the VM to see if we could have some more clues.<br>
<br>
The first thing we noticed is that the first time the GC runs, the mournQueue is nil. This is of course expected because the new finalization mechanism was not active and then there was no need to create the mournQueue. We saw that the mournQueue is actually created in a lazy fashion when putting queuing a mourned object (I refer myself to #queueMourner: and #ensureRoomOnObjStackAt:). So the second time the GC passes, the mournQueue is there. So far ok, but still crashing.<br>
<br>
The crash happens in the call to<br>
<br>
markAndTraceObjStackandContents(GIV(mournQueue), 1);<br>
<br>
after the<br>
<br>
    if (!markAndTraceContents) {<br>
       return;<br>
    }<br>
<br>
But when understanding why, it starts being less clear to us :). We used the printObjStack() function and we saw that:<br>
<br>
call printObjStack(markStack)<br>
call printObjStack(weaklingStack)<br>
<br>
and we saw in the console some output that makes sense. However, printing the mournQueue in the same manner produces some strange output<br>
<br>
call printObjStack(mournQueue)<br>
<br>
head  0xb06e980 cx 18 (18) fmt 10 (10) sz 4092 (4092) myx: 4098 (4098) unmkd<br>
    topx: 14 next:        0x0 free:        0x0<br>
<br>
We noticed that free and next are 0x0 while the others are not...<br>
<br>
Finally we saw there is isValidObjStack(), that gave us the following results:<br>
<br>
call isValidObjStack(markStack) =&gt; 1<br>
<br>
call isValidObjStack(weaklingStack) =&gt; 0<br>
p objStackInvalidBecause = &quot;marking but page is unmarked&quot;<br>
<br>
call isValidObjStack(mournQueue) =&gt; 0<br>
p objStackInvalidBecause = &quot;marking but page is unmarked&quot;<br>
<br>
<br>
So we assume that the stack creation is wrong? We are a bit lost in here.<br>
<br>
Guille and Pablo<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>