<div dir="ltr"><div>Thanks to Stephane, we have a reproducible case and might understand why/how this happens...</div><div>Unfortunately, I have no idea what the algorithm does, it would deserve some more documentation.</div><div>Is this a classical algorithm that can be found in litterature?<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le dim. 29 déc. 2019 à 18:50, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Nicolas, Hi Stéphane,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Dec 28, 2019 at 2:24 PM Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <div dir="ltr"><div>I forgot to say that I had an assert failure report:</div><div><br></div><div>leftEdge && rightEdge 1398</div><div><br></div><div>Looking around line 1398: <br></div><div><br></div><div> /*-- search for the next top edge which will be the right edge --*/<br> assert(aetStart < aetSize);<br> if(!fillList->firstFace)<br> rightEdge = aetData[aetStart++]; /* If no current top fill just use the next edge */<br> else while(aetStart < aetSize) { /* Search for the next top edge in the AET */<br> rightEdge = aetData[aetStart];<br> /* If we have an intersection use the intersection edge */<br> if(nextIntersection->xValue <= rightEdge->xValue) {<br> rightEdge = nextIntersection;<br> break;<br> }<br> aetStart++;<br> /* Check if this edge is on top */<br> assert(fillList->firstFace);<br> {<br> double xValue = rightEdge->xValue * B3D_FixedToFloat;<br> B3DPrimitiveFace *topFace = fillList->firstFace;<br> if( rightEdge->leftFace == topFace ||<br> rightEdge->rightFace == topFace ||<br> rightEdge->zValue < zValueAt(topFace, xValue, yValue))<br> break; /* rightEdge is on top */<br> }<br> /* If the edge is not on top toggle its (back) fills */<br> b3dToggleBackFills(fillList, rightEdge, yValue, nextIntersection);<br> rightEdge = NULL;<br> }<br> /*-- end of search for next top edge --*/<br><br> /*-- Now do the drawing from leftEdge to rightEdge --*/<br>#if 1 /* This assert fails in rare cases; the fix is not understood. eem */<br> assert(leftEdge && rightEdge);<br>#else<br> if(!leftEdge || !rightEdge)<br> FAIL_UPDATING(B3D_NO_MORE_EDGES); // another segfault<br> //FAIL_PAINTING(B3D_NO_MORE_EDGES); // blow up in allocating edges<br>#endif<br> if(fillList->firstFace) {<br> /* Note: We fill *including* leftX and rightX */<br> int leftX = (leftEdge->xValue >> B3D_FixedToIntShift) + 1;<br> int rightX = (rightEdge->xValue >> B3D_FixedToIntShift);</div><div><br></div><div>So I'm pretty sure that we went thru:</div><div><br></div><div> /* If the edge is not on top toggle its (back) fills */<br> b3dToggleBackFills(fillList, rightEdge, yValue, nextIntersection);<br> rightEdge = NULL;</div><div><br></div><div>if intention of #if 1... assert(...) was probably to debug the case of failure...</div><div>But it was left in the release. Maybe it would be safer to replace with #ifdef DEBUG or something like that?</div><div>Eliot?<br></div></div></blockquote><br>I remember now.<br><br>The original code read<br><br>- assert(rightEdge);<br><br>and this din't catch the crash. So I added the #else arm:<br><br>+ if(!leftEdge || !rightEdge)<br>+ FAIL_PAINTING(B3D_NO_MORE_EDGES); // blow up in allocating edges<br><br>which caused the system to fail not being able to allocate edges. So I tried an alternative:<br><br>+ if(!leftEdge || !rightEdge)<br>+ FAIL_UPDATING(B3D_NO_MORE_EDGES); // another segfault<br><br>which caused segfaults. So I added the stronger assert, and ifdefed out my two attempts at failing correctly in the #else arm.<br><br>+ assert(leftEdge && rightEdge);<br><br>So by all means strip the code back to the assert, but I think that the information that both of those attempts at remediation, FAIL_PAINTING(B3D_NO_MORE_EDGES); and FAIL_UPDATING(B3D_NO_MORE_EDGES);, failed and for different reasons might be useful to know.</div><br>The question is under what circumstances does the assert(leftEdge && rightEdge); fail?<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le sam. 28 déc. 2019 à 23:04, Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Running SqueakDebug.app in lldb, I get:</div><div><br></div><div>Process 61332 stopped<br>* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)<br> frame #0: 0x09f17c07 Squeak3D`b3dMainLoop(state=0x09f1928c, stopReason=0) at b3dMain.c:1407:32<br> 1404 if(fillList->firstFace) {<br> 1405 /* Note: We fill *including* leftX and rightX */<br> 1406 int leftX = (leftEdge->xValue >> B3D_FixedToIntShift) + 1;<br>-> 1407 int rightX = (rightEdge->xValue >> B3D_FixedToIntShift);<br> 1408 B3DPrimitiveFace *topFace = fillList->firstFace;<br> 1409 <br> 1410 if(leftX < 0) leftX = 0;<br>Target 0: (Squeak) stopped.<br>(lldb) print rightEdge<br>(B3DPrimitiveEdge *) $0 = 0x00000000<br>(lldb) print leftEdge<br>(B3DPrimitiveEdge *) $1 = 0x0617a49c<br>(lldb) bt<br>* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)<br> * frame #0: 0x09f17c07 Squeak3D`b3dMainLoop(state=0x09f1928c, stopReason=0) at b3dMain.c:1407:32<br> frame #1: 0x09f0cb23 Squeak3D`b3dStartRasterizer at Squeak3D.c:1704:12<br> frame #2: 0x05d01398<br> frame #3: 0x00002f52 Squeak`interpret at gcc3x-cointerp.c:2749:3</div><div><br></div><div>So why rightEdge is a null pointer?</div><div>If you already examined the code, you may have an idea...<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le sam. 28 déc. 2019 à 22:55, Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Stephane,</div><div>I confirm that I can reproduce the crash with an up-to-date VM (on OSX).<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le sam. 28 déc. 2019 à 19:20, Stéphane Rollandin <<a href="mailto:lecteur@zogotounga.net" target="_blank">lecteur@zogotounga.net</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
Hello all,<br>
<br>
For my first post on this list, I would like to submit the bug that <br>
prevents one of my game (this one: <br>
<a href="http://www.zogotounga.net/comp/guardians.htm" rel="noreferrer" target="_blank">http://www.zogotounga.net/comp/guardians.htm</a>) to work reliably.<br>
<br>
I spent quite some time on this, and I ended up with a nice and concise <br>
way to crash the Squeak3D plugin. The image is available at:<br>
<br>
<a href="http://www.zogotounga.net/swap/crashlab3.zip" rel="noreferrer" target="_blank">http://www.zogotounga.net/swap/crashlab3.zip</a><br>
<br>
Instructions to crash the VM are detailed therein.<br>
<br>
The 3D scene is very simple, there are only three objects. The crash<br>
seems related to a race condition, because inserting a simple delay in<br>
the code prevents it - this is detailed in the image itself.<br>
<br>
I have spent days studying the Smalltalk code, and could not see<br>
anything wrong with what is sent to the plugin. It looks to my<br>
uninformed eyes as a problem of shared memory, where one rasterizing<br>
operation messes up with another happening in parallel (although no<br>
processed is being forked on the Smalltalk side).<br>
<br>
<br>
Stef<br>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><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></div></div></div></div></div></div>
</blockquote></div>