<div dir="ltr"><div>Hi Bernd</div><div><br></div><div>If a native functions returns a pointer (like strcat()), FFM has no idea how long the associated data structure. So it returns a memory segment with length 0. So when 
<span class="gmail-pl-en">getUtf8String() is called, it will inevitably access memory outside the memory segment and you get the described exception.</span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">In this special case, FFM could at least have known the total length of the allocated memory as it was allocated by FFM in the first place. But usually the memory is allocated by the called method (e.g. by strdup()). <br></span></div><div><span class="gmail-pl-en"><br></span></div><div>To fix it, you have at least two options:</div><div><br></div><div>1. Simply return buf.<span class="gmail-pl-en">getUtf8String</span>(0) as strcat() always returns the first parameter.</div><div>2. Create a new MemorySegment with the correct length like so:</div><div><br></div><div>var res = 
((<span class="gmail-pl-smi">MemorySegment</span>)<span class="gmail-pl-s1">strcat</span>.<span class="gmail-pl-en">invokeExact</span>(<span class="gmail-pl-s1">buf</span>, <span class="gmail-pl-s1">other</span>));</div><div>var seg = MemorySegment.ofAddress(res.address(), buf.length(), res.scope());</div><div>return seg.<span class="gmail-pl-en">getUtf8String</span>(0);</div><div><br></div><div>This creates a new MemorySegment without allocating new memory. "buf", "res", and "seg" all point to the same memory.<br>



</div><div><br></div><div>Note that 
<span class="gmail-pl-s1">"s1</span>.<span class="gmail-pl-en">length</span>() + <span class="gmail-pl-s1">s2</span>.<span class="gmail-pl-en">length</span>() + <span class="gmail-pl-c1">1</span>" isn't the correct way to calculate the required buffer length. The buffer length needs to be specified in bytes, but s1.length() and s2.length() return the length in UTF-16 code units.</div><div><br></div><div>Regards</div><div>Manuel<br></div><div><span class="gmail-pl-en"><br></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am Mi., 4. Jan. 2023 um 08:53 Uhr schrieb Bernd Müller <<a href="mailto:bernd.mueller@ostfalia.de">bernd.mueller@ostfalia.de</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Dear Gavin,<br>
<br>
thank you very much for extracting the code.<br>
Eventually, it would be much easier to do a "mvn test". To do so<br>
please clone:<br>
<a href="https://github.com/BerndMuller/ffm2" rel="noreferrer" target="_blank">https://github.com/BerndMuller/ffm2</a><br>
<br>
Error still:<br>
StdLibTest.foo:49->strcat:60 » IndexOutOfBounds Out of bound access on segment MemorySegment{ array: <br>
Optional.empty address:139631472807584 limit: 0 }; new offset = 0; new length = 1<br>
<br>
looks for me like strcat changes the array size<br>
<br>
Kind Regards,<br>
<br>
Bernd<br>
<br>
Am 04.01.23 um 02:12 schrieb Gavin Ray:<br>
> Maurizio, the code I was able to get out of the email is below:<br>
> <br>
> public class StdLibTest {<br>
> <br>
> private static MethodHandle strlen; // C's strlen() function<br>
> private static MethodHandle strcat; // C's strcat() function<br>
> <br>
>      @BeforeAll<br>
> public static void locateFunctions() {<br>
> Linker linker = Linker.nativeLinker();<br>
> strlen = linker.downcallHandle(linker.defaultLookup().find("strlen").get(),<br>
> FunctionDescriptor.of(JAVA_LONG, ADDRESS));<br>
> strcat = linker.downcallHandle(linker.defaultLookup().find("strcat").get(),<br>
> FunctionDescriptor.of(ADDRESS, ADDRESS, ADDRESS));<br>
>      }<br>
> <br>
> <br>
>      @Test<br>
> public void strlen() throws Throwable {<br>
> try (Arena arena = Arena.openConfined()) {<br>
> MemorySegment segment = arena.allocateUtf8String("Hello");<br>
> int length = (int) (long) strlen.invoke(segment);<br>
> Assertions.assertSame(5, length);<br>
>          }<br>
>      }<br>
> <br>
>      @Test<br>
> public void foo() throws Throwable {<br>
> String result = strcat("hello", "world");<br>
>      }<br>
>      /**<br>
>       * This is a one to one copy of strcat test taken from  StdLibTest.java test from OpenJDK<br>
>       */<br>
> String strcat(String s1, String s2) throws Throwable {<br>
> try (var arena = Arena.openConfined()) {<br>
> MemorySegment buf = arena.allocate(s1.length() + s2.length() + 1);<br>
> buf.setUtf8String(0, s1);<br>
> MemorySegment other = arena.allocateUtf8String(s2);<br>
> return ((MemorySegment)strcat.invokeExact(buf, other)).getUtf8String(0);<br>
>          }<br>
>      }<br>
> }<br>
> <br>
> On Tue, Jan 3, 2023 at 12:55 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank">maurizio.cimadamore@oracle.com</a> <br>
> <mailto:<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank">maurizio.cimadamore@oracle.com</a>>> wrote:<br>
> <br>
>     Hi Bernd,<br>
>     this mailing list truncates attachments. If you want us to look at some<br>
>     code you will have to paste it somewhere :-)<br>
> <br>
>     Cheers<br>
>     Maurizio<br>
> <br>
>     On 03/01/2023 17:14, Bernd Müller wrote:<br>
>      > Dear all,<br>
>      ><br>
>      > I try to train FFM. I even master quick sort but became desperate on<br>
>      > strcon.<br>
>      ><br>
>      > Attached you will find a Maven project with the strcon test copied one<br>
>      > to one from<br>
>      > OpenJDK 20 sources.<br>
>      ><br>
>      > "mvn test" results in<br>
>      ><br>
>      > [ERROR] Errors:<br>
>      > [ERROR]   StdLibTest.foo:49->strcat:60 » IndexOutOfBounds Out of bound<br>
>      > access on segment MemorySegment{ array: Optional.empty<br>
>      > address:139636573277136 limit: 0 }; new offset = 0; new length = 1<br>
>      ><br>
>      > I am running OpenJDK 64-Bit Server VM (build 20-ea+29-2280, mixed<br>
>      > mode, sharing) on Fedora 36.<br>
>      ><br>
>      > Please, can someone help ?<br>
>      ><br>
>      > Kind Regards,<br>
>      ><br>
>      > Bernd<br>
>      ><br>
> <br>
<br>
<br>
-- <br>
Prof. Dr. Bernd Müller<br>
<br>
Ostfalia<br>
Hochschule für angewandte Wissenschaften<br>
- Hochschule Braunschweig/Wolfenbüttel -<br>
Fakultät Informatik<br>
Salzdahlumer Straße 46/48<br>
38302 Wolfenbüttel<br>
<br>
Tel  +49 5331 939 31160<br>
Fax  +49 5331 939 31004<br>
Web  <a href="http://www.ostfalia.de" rel="noreferrer" target="_blank">www.ostfalia.de</a> / <a href="http://www.pdbm.de" rel="noreferrer" target="_blank">www.pdbm.de</a><br>
</blockquote></div>