<div dir="ltr">Hi Ben,<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 2, 2016 at 5:51 AM, Ben Coman <span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
The more experienced here probably know a lot of this, but I found it<br>
quite interesting so I thought I&#39;d share...<br>
<br>
<a href="https://www.owasp.org/index.php/C-Based_Toolchain_Hardening" rel="noreferrer" target="_blank">https://www.owasp.org/index.<wbr>php/C-Based_Toolchain_<wbr>Hardening</a></blockquote><div><br></div><div>TL;DR, but I skimmed it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">My biggest take away is the emphasis on using asserts.  My<br>
professional C programming experience was only a short stint 20 years<br>
ago in a graduate position where asserts were never discussed.  So<br>
I&#39;ve never used asserts and it was particularly enlightening to<br>
read... &quot;in the time it takes for you to write a printf or NSLog<br>
statement, you could have written an assert. Unlike the printf or<br>
NSLog which are often removed when no longer needed, the assert stays<br>
active forever.&quot;<br></blockquote><div><br></div><div>+1</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">In relation to my own (potential) contributions to the VM, I&#39;d be<br>
interested to learn if there are any particular aspects from that<br>
article that particularly:<br>
* resonate with current practices<br></blockquote><div><br></div><div>Sure.  In ParcPlace I moved from just having Debug and Release builds to Debug, Assert (-O1) and Production builds cuz often the Debug build was frustratingly slow.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* areas that could be improved<br></blockquote><div><br></div><div>With the appropriate setup for third-party libraries we can use Debug builds of third-party libraries with Debug and Assert VM builds, and Production builds of third-party libraries with the Production VM builds.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* are adverse to personal experience<br></blockquote><div><br></div><div>No.  This is good style.  The code is both better commented (asserts often state important invariants) and the VM is effectively full of tests.  This is at least one reason why we get away with not having micro tests for VM subcomponents, which are difficult to write since the VM is designed to consume an entire Smalltalk image and execute an entire Smalltalk system.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Of course there are already production, debug and assert builds.  And<br>
it concurs with what I&#39;ve read on the list about avoiding autotools.<br></blockquote><div><br></div><div>Good to hear!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
The problem with dependency rebuilds when CFLAGS change between<br>
production/debug builds was enlightening (if obvious in hindsight).  I<br>
guess this is why each build type has its own directory.<br></blockquote><div><br></div><div>Exactly.  The builds must be kept separate; otherwise they would pollute, causing confusion and delay ;-)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">One thing I don&#39;t quite get is &quot;Everywhere you place an if statement<br>
for validation or checking, you should have an assert. Everywhere you<br>
have an assert for validation or checking, you should have an if<br>
statement. They go hand-in-hand.&quot;<br>
Indeed, perusing asserts in the repository [1] doesn&#39;t show any nearby<br>
if statements, so maybe that statement is a stretch??<br></blockquote><div><br></div><div>The assert scheme includes assert for use in ifs.  A normal assert is an expression that produces a warning if it is false, and is compiled only in debug and assert builds.  An asserts is an expression that produces a warning if it is false in debug and assert builds, but is still evaluated in all builds.  So if you want an if combined with an assert you use asserta, e.g. see</div><div><br></div><div>CoInterpreter&gt;&gt;callbackEnter: callbackID</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;Re-enter the interpreter for executing a callback&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>| currentCStackPointer currentCFramePointer savedReenterInterpreter</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>  wasInMachineCode calledFromMachineCode |</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;volatile&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;export: true&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #currentCStackPointer type: #&#39;void *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #currentCFramePointer type: #&#39;void *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #callbackID type: #&#39;sqInt *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #savedReenterInterpreter type: #&#39;jmp_buf&#39;&gt;</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;For now, do not allow a callback unless we&#39;re in a primitiveResponse&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>(self asserta: primitiveFunctionPointer ~= 0) ifFalse:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>[^false].</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>self assert: primFailCode = 0.</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;Check if we&#39;ve exceeded the callback depth&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>(self asserta: jmpDepth &lt; MaxJumpBuf) ifFalse:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>[^false].</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>jmpDepth := jmpDepth + 1.</div><div>...</div><div><br></div><div>So the asserts are eliminated in production builds and the assertas remain but do not produce a warning, so the code is equivalent to</div><div><br></div><div><div>callbackEnter: callbackID</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;Re-enter the interpreter for executing a callback&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>| currentCStackPointer currentCFramePointer savedReenterInterpreter</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>  wasInMachineCode calledFromMachineCode |</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;volatile&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;export: true&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #currentCStackPointer type: #&#39;void *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #currentCFramePointer type: #&#39;void *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #callbackID type: #&#39;sqInt *&#39;&gt;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&lt;var: #savedReenterInterpreter type: #&#39;jmp_buf&#39;&gt;</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;For now, do not allow a callback unless we&#39;re in a primitiveResponse&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>primitiveFunctionPointer ~= 0 ifFalse:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>[^false].</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>&quot;Check if we&#39;ve exceeded the callback depth&quot;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>jmpDepth &lt; MaxJumpBuf ifFalse:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                </span>[^false].</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>jmpDepth := jmpDepth + 1.</div></div><div><br></div><div><br></div><div>You&#39;ll also find eassert: which is for expensive asserts that are evaluated only if enabled.</div><div>In the simulator this is controlled by the VMClass class var ExpensiveAsserts.</div><div>In compiled C VMs this is controlled by the expensiveAsserts variable, which must be set by hand in lldb/gdb et al.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">[1] <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/search?l=c&amp;q=assert&amp;type=Code&amp;utf8=%E2%9C%93" rel="noreferrer" target="_blank">https://github.com/<wbr>OpenSmalltalk/opensmalltalk-<wbr>vm/search?l=c&amp;q=assert&amp;type=<wbr>Code&amp;utf8=%E2%9C%93</a><br>
<br>
cheers -ben<br>
</blockquote></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>