<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 27 November 2017 at 00:24, Todd Blanchard <span dir="ltr"><<a href="mailto:tblanchard@mac.com" target="_blank">tblanchard@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div style="word-wrap:break-word">i'm getting the idea that we should probably write a test suite/library for FFI</div></blockquote><div><br></div><div>I noticed these...</div><div>* <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/unix/plugins/SqueakFFIPrims/ffi-test-main.c" target="_blank">https://github.com/OpenSmallta<wbr>lk/opensmalltalk-vm/blob/Cog/<wbr>platforms/unix/plugins/<wbr>SqueakFFIPrims/ffi-test-main.c</a><br></div><div>* <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/Cross/plugins/SqueakFFIPrims/sqFFITestFuncs.c" target="_blank">https://github.com/OpenSmall<wbr>talk/opensmalltalk-vm/blob/<wbr>Cog/platforms/Cross/plugins/<wbr>SqueakFFIPrims/sqFFITestFuncs.<wbr>c</a></div><div>* <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/Cross/plugins/IA32ABI/AlienSUnitTestProcedures.c" target="_blank">https://github.com/OpenSmall<wbr>talk/opensmalltalk-vm/blob/<wbr>Cog/platforms/Cross/plugins/<wbr>IA32ABI/AlienSUnitTestProcedur<wbr>es.c</a></div><div><br></div><div>These look like c-code test frames for FFI.  Could these be built by the OpenSmalltalk CI to be normally shipped with the VM so that Image-side CI can test against them?</div><div><br></div><div>And also some general info...</div><div>* <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/platforms/unix/plugins/SqueakFFIPrims/00README" target="_blank">https://github.com/OpenSmall<wbr>talk/opensmalltalk-vm/blob/<wbr>Cog/platforms/unix/plugins/<wbr>SqueakFFIPrims/00README</a></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><br><div><blockquote type="cite"><div>On Nov 24, 2017, at 12:54 AM, Ben Coman <<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>> wrote:</div><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><br class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-interchange-newline"><br><div class="gmail_quote">On 24 November 2017 at 13:16, Ben Coman<span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>></span><span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"> </span>wr<wbr>ote:<br><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"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862gmail-h5">On 22 November 2017 at 21:59, Ben Coman<span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>></span><span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"> </span>wr<wbr>ote:<br><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"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862gmail-m_8524537758069216380gmail-m_-4929630517411459228gmail-">On 22 November 2017 at 13:38, Todd Blanchard<span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:tblanchard@mac.com" target="_blank">tblanchard@mac.com</a>></span><span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862Apple-converted-space"><wbr> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div style="word-wrap:break-word">I've been trying to track this down for a couple weeks now.</div></blockquote></span></div></div></div></blockquote></div></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><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 class="gmail_extra"><div class="gmail_quote"><div><div class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862gmail-h5"><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 class="gmail_extra"><div class="gmail_quote"><span class="gmail-m_-4607556448884927622m_-3452065927662814111gmail-m_7527885605307787862gmail-m_8524537758069216380gmail-m_-4929630517411459228gmail-"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>I have concluded that structs passed by value to functions on the 64 bit VM are not properly populated.  The struct's memory is all zero'd.</div><div><br></div><div>I found this while trying to work with LibClang and found that functions that fetched code locations from code ranges always returned invalid zero'd locations.  After spending some time with lldb I have traced the problem into the native code and found that the argument is not correct.</div><div><br></div><div>I've carved out the wee bit of clang to reproduce this in a tiny library.</div><div><br></div><div>The gist of it is below and the entire file is included.  Basically the struct passed to the function clang_getRangeStart is zero'd memory regardless of the data I send from the image side.</div></div></blockquote></span></div></div></div></blockquote></div></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote><div><br></div><div>My last analysis discovered something interesting about strings defined inside shared libraries being handled differently, but only later realised I had chased the wrong rabbit down the hole.  </div><div> <br></div><div>I've now investigated the premise you actually poses, and I agree, that structs being zero is some cases.  </div><div>The attached zipfile containing  libstruct.c  a few comparison cases - three "good" layouts that work fine and one "bad" that mostly gets zeros but sometimes other weird numbers.  There is a Makefile with three main targets:</div><div>1. make layout - statically compiles  libstruct.c  and runs produced  a.out  to display structure layouts </div><div><div><br></div><div>2. make run - downloads Pharo, starts it loading  LibStruct.st  , then you manually run LibStruct>>>LibStructTest>>#testStructs and observe structure values on console</div><div><br></div><div>3. make debug - starts LLDB to run Pharo with breakpoints pre-configured for when you run #testStructs.  </div><div>   Note Pharo will freeze and you need to move to LLDB.  Try these commands... </div><div>      frame variable</div><div>      call print_struct(&GoodStruct1_fmt, &aStruct)</div></div><div>      continue</div><div><br></div><div>That works on Ubuntu 16.04 64 bit. </div><div>You will need to tune it for OSX.</div><div>clang and lldb are required.</div><div><br></div><div>================================<br></div><div>The offsets configured in the class variables of all ExternalStructs </div><div>correctly matches that reported by the C code test frame results here...</div><div><br></div><div>$ make layout        </div><div><div>clang -g libstruct.c</div><div>./a.out</div><div><br></div><div>GoodStruct1:</div><div><span style="white-space:pre">    </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 </div><div><span style="white-space:pre">        </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 </div><div>GoodStruct2:</div><div><span style="white-space:pre">     </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 </div><div><span style="white-space:pre">        </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 </div><div><span style="white-space:pre">        </span>void*:ptr_data:   <span style="white-space:pre"> </span>09 8 </div><div>GoodStruct3:</div><div><span style="white-space:pre">     </span>void*:ptr_data:   <span style="white-space:pre"> </span>01 8 </div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>09 4 </div><div><span style="white-space:pre">        </span>uint32_t:int2:   <span style="white-space:pre">  </span>13 4 </div><div>BadStruct:</div><div><span style="white-space:pre">       </span>void*:ptr_data1:   <span style="white-space:pre">        </span>01 8 </div><div><span style="white-space:pre">        </span>void*:ptr_data2:   <span style="white-space:pre">        </span>09 8 </div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>17 4 </div><div><span style="white-space:pre">        </span>uint32_t:int2:   <span style="white-space:pre">  </span>21 4 </div><div><br></div><div>================================</div><div><br></div><div>$ make run   </div><div><div>clang -g -o libstruct.so -shared -fPIC libstruct.c</div><div>getpharo/pharo-vm/lib/pharo/5.0-201707201942/pharo getpharo/Pharo.image ../LibStruct.st</div></div><div><br></div><div>Now manually browse to and run  LibStruct>>>LibStructTest>>#testStructs</div><div><div><div>LibStructTest>>testStructs</div><div><span style="white-space:pre">       </span>|good1Struct good2Struct good3Struct badStruct |<br></div><div><span style="white-space:pre">    </span></div><div><span style="white-space:pre">      </span>good1Struct    := GoodStruct1    new int1: 2; int2: 3.</div><div><span style="white-space:pre">    </span>good2Struct    := GoodStruct2    new int1: 2; int2: 3; ptr_force_int: 4.</div><div><span style="white-space:pre">  </span>good3Struct    := GoodStruct3    new int1: 2; int2: 3; ptr_force_int: 4.</div><div><span style="white-space:pre">  </span>badStruct      := BadStruct      new int1: 2; int2: 3; ptr_force_int1: 4; ptr_force_int1: 5.</div><div><span style="white-space:pre">    </span></div><div><span style="white-space:pre">      </span>self assert: (LibStruct tryGood1: good1Struct)       equals: 6.<span style="white-space:pre">  </span></div><div><span style="white-space:pre">      </span>self assert: (LibStruct tryGood2: good2Struct)       equals: 6.</div><div><span style="white-space:pre">   </span>self assert: (LibStruct tryGood3: good3Struct)       equals: 6.</div><div><span style="white-space:pre">   </span>"Problem exposed in next line"</div><div><span style="white-space:pre">      </span>self assert: (LibStruct tryBad: badStruct)           equals: 6.</div></div></div><div><br></div><div>which on console produces...</div><div><br></div><div><div>GoodStruct1:</div><div><span style="white-space:pre">      </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 = 03 00 00 00</div><div>GoodStruct2:</div><div><span style="white-space:pre"> </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 = 03 00 00 00</div><div><span style="white-space:pre">    </span>void*:ptr_data:   <span style="white-space:pre"> </span>09 8 = 04 00 00 00 00 00 00 00</div><div>GoodStruct3:</div><div><span style="white-space:pre">     </span>void*:ptr_data:   <span style="white-space:pre"> </span>01 8 = 04 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>09 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>13 4 = 03 00 00 00</div><div>BadStruct:</div><div><span style="white-space:pre">   </span>void*:ptr_data1:   <span style="white-space:pre">        </span>01 8 = 00 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>void*:ptr_data2:   <span style="white-space:pre">        </span>09 8 = 00 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>17 4 = 29 03 03 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>21 4 = 00 00 00 00</div></div><div><br></div><div><div>Comparing GoodStruct3 and BadStruct, it seems one pointer is handled fine, but not two.</div><div>The first time this is run after Image boots seems like BadStruct gets some random data.</div></div><div><br></div><div>================================</div><div>In same image, subsequent runs of  LibStruct>>>LibStructTest>>testStructs     </div><div>give only all zeros for BadStruct, as Todd observed.</div><div><br></div><div>GoodStruct1:</div><div><span style="white-space:pre">   </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 = 03 00 00 00</div><div>GoodStruct2:</div><div><span style="white-space:pre"> </span>uint32_t:int1:   <span style="white-space:pre">  </span>01 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>05 4 = 03 00 00 00</div><div><span style="white-space:pre">    </span>void*:ptr_data:   <span style="white-space:pre"> </span>09 8 = 00 00 00 00 00 00 00 00</div><div>GoodStruct3:</div><div><span style="white-space:pre">     </span>void*:ptr_data:   <span style="white-space:pre"> </span>01 8 = 00 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>09 4 = 02 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>13 4 = 03 00 00 00</div><div>BadStruct:</div><div><span style="white-space:pre">   </span>void*:ptr_data1:   <span style="white-space:pre">        </span>01 8 = 00 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>void*:ptr_data2:   <span style="white-space:pre">        </span>09 8 = 00 00 00 00 00 00 00 00</div><div><span style="white-space:pre">        </span>uint32_t:int1:   <span style="white-space:pre">  </span>17 4 = 00 00 00 00</div><div><span style="white-space:pre">    </span>uint32_t:int2:   <span style="white-space:pre">  </span>21 4 = 00 00 00 00</div></div><div><br></div><div><br></div><div>cheers -ben</div><div><br></div></div></div></div>