Can't find the bug
Manuel Bleichenbacher
manuel.bleichenbacher at gmail.com
Wed Jan 4 10:22:11 UTC 2023
Hi Bernd
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 getUtf8String() is called, it will inevitably access
memory outside the memory segment and you get the described exception.
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()).
To fix it, you have at least two options:
1. Simply return buf.getUtf8String(0) as strcat() always returns the first
parameter.
2. Create a new MemorySegment with the correct length like so:
var res = ((MemorySegment)strcat.invokeExact(buf, other));
var seg = MemorySegment.ofAddress(res.address(), buf.length(), res.scope());
return seg.getUtf8String(0);
This creates a new MemorySegment without allocating new memory. "buf",
"res", and "seg" all point to the same memory.
Note that "s1.length() + s2.length() + 1" 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.
Regards
Manuel
Am Mi., 4. Jan. 2023 um 08:53 Uhr schrieb Bernd Müller <
bernd.mueller at ostfalia.de>:
> Dear Gavin,
>
> thank you very much for extracting the code.
> Eventually, it would be much easier to do a "mvn test". To do so
> please clone:
> https://github.com/BerndMuller/ffm2
>
> Error still:
> StdLibTest.foo:49->strcat:60 » IndexOutOfBounds Out of bound access on
> segment MemorySegment{ array:
> Optional.empty address:139631472807584 limit: 0 }; new offset = 0; new
> length = 1
>
> looks for me like strcat changes the array size
>
> Kind Regards,
>
> Bernd
>
> Am 04.01.23 um 02:12 schrieb Gavin Ray:
> > Maurizio, the code I was able to get out of the email is below:
> >
> > public class StdLibTest {
> >
> > private static MethodHandle strlen; // C's strlen() function
> > private static MethodHandle strcat; // C's strcat() function
> >
> > @BeforeAll
> > public static void locateFunctions() {
> > Linker linker = Linker.nativeLinker();
> > strlen =
> linker.downcallHandle(linker.defaultLookup().find("strlen").get(),
> > FunctionDescriptor.of(JAVA_LONG, ADDRESS));
> > strcat =
> linker.downcallHandle(linker.defaultLookup().find("strcat").get(),
> > FunctionDescriptor.of(ADDRESS, ADDRESS, ADDRESS));
> > }
> >
> >
> > @Test
> > public void strlen() throws Throwable {
> > try (Arena arena = Arena.openConfined()) {
> > MemorySegment segment = arena.allocateUtf8String("Hello");
> > int length = (int) (long) strlen.invoke(segment);
> > Assertions.assertSame(5, length);
> > }
> > }
> >
> > @Test
> > public void foo() throws Throwable {
> > String result = strcat("hello", "world");
> > }
> > /**
> > * This is a one to one copy of strcat test taken from
> StdLibTest.java test from OpenJDK
> > */
> > String strcat(String s1, String s2) throws Throwable {
> > try (var arena = Arena.openConfined()) {
> > MemorySegment buf = arena.allocate(s1.length() + s2.length() + 1);
> > buf.setUtf8String(0, s1);
> > MemorySegment other = arena.allocateUtf8String(s2);
> > return ((MemorySegment)strcat.invokeExact(buf, other)).getUtf8String(0);
> > }
> > }
> > }
> >
> > On Tue, Jan 3, 2023 at 12:55 PM Maurizio Cimadamore <
> maurizio.cimadamore at oracle.com
> > <mailto:maurizio.cimadamore at oracle.com>> wrote:
> >
> > Hi Bernd,
> > this mailing list truncates attachments. If you want us to look at
> some
> > code you will have to paste it somewhere :-)
> >
> > Cheers
> > Maurizio
> >
> > On 03/01/2023 17:14, Bernd Müller wrote:
> > > Dear all,
> > >
> > > I try to train FFM. I even master quick sort but became desperate
> on
> > > strcon.
> > >
> > > Attached you will find a Maven project with the strcon test
> copied one
> > > to one from
> > > OpenJDK 20 sources.
> > >
> > > "mvn test" results in
> > >
> > > [ERROR] Errors:
> > > [ERROR] StdLibTest.foo:49->strcat:60 » IndexOutOfBounds Out of
> bound
> > > access on segment MemorySegment{ array: Optional.empty
> > > address:139636573277136 limit: 0 }; new offset = 0; new length = 1
> > >
> > > I am running OpenJDK 64-Bit Server VM (build 20-ea+29-2280, mixed
> > > mode, sharing) on Fedora 36.
> > >
> > > Please, can someone help ?
> > >
> > > Kind Regards,
> > >
> > > Bernd
> > >
> >
>
>
> --
> Prof. Dr. Bernd Müller
>
> Ostfalia
> Hochschule für angewandte Wissenschaften
> - Hochschule Braunschweig/Wolfenbüttel -
> Fakultät Informatik
> Salzdahlumer Straße 46/48
> 38302 Wolfenbüttel
>
> Tel +49 5331 939 31160
> Fax +49 5331 939 31004
> Web www.ostfalia.de / www.pdbm.de
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20230104/10dc41e7/attachment-0001.htm>
More information about the panama-dev
mailing list