jextract: offset not multiple of alignment, causing ExceptionInInitializerError

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Jan 15 11:30:30 UTC 2021


Aha!

That's interesting. Pretty sure jextract is completely oblivious about 
that. Of course the solution would be to recover the pragma and tweak 
the layout alignment accordingly. I have a vague feeling that what 
"makes sense" is not going to be that easy using the clang API :-)

We'll take  a look. Thanks for reporting this.

Filed this:
https://bugs.openjdk.java.net/browse/JDK-8259832

Maurizio

On 15/01/2021 08:31, Sebastian Stenzel wrote:
> I had another look at the original header file (macOS: usr/include/sys/fcntl.h). Turns out, this struct is surrounded by a pack(4), which should explain this behaviour:
>
> #pragma pack(4)
>
> struct log2phys {
>          unsigned int    l2p_flags;       /* unused so far */
>          off_t           l2p_contigbytes; /* F_LOG2PHYS:     unused so far */
>                                           /* F_LOG2PHYS_EXT: IN:  number of bytes to be queried */
>                                           /*                 OUT: number of contiguous bytes at this position */
>          off_t           l2p_devoffset;   /* F_LOG2PHYS:     OUT: bytes into device */
>                                           /* F_LOG2PHYS_EXT: IN:  bytes into file */
>                                           /*                 OUT: bytes into device */
> };
>
> #pragma pack()
>
> Question is: Is jextract _expected_ to be aware of this?
>
>
>> On 14. Jan 2021, at 23:01, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
>>
>> That layout looks odd/wrong.
>>
>> It seems like there might be some padding missing. Note that you have a 64 bit field that is not 64 bit aligned - so accessing it might be slower. I believe in most compilers 32 bit of padding would be inserted.
>>
>> Or, if this is really the way the struct is laid out, jextract should have relaxed the alignment requirements for "l2p_contigbytes". As it stands, the jextract layout seems bogus. If you have access to the code, I'd suggest adding:
>>
>> C_LONG_LONG.withName("l2p_contigbytes").withAlignmentBits(32)
>>
>> This should allow you to initialize correctly.
>>
>> Maurizio
>>
>> On 14/01/2021 21:34, Sebastian Stenzel wrote:
>>> Hey,
>>>
>>> Today I noticed a strange problem related to the MemoryLayout generated by jextract for the following struct:
>>>
>>> ```
>>> struct log2phys {
>>> 	u_int32_t	l2p_flags;	
>>> 	off_t		l2p_contigbytes;
>>> 	off_t		l2p_devoffset;
>>> };
>>> ```
>>>
>>> The generated layout looks like this:
>>>
>>> ```
>>> static final MemoryLayout log2phys$struct$LAYOUT_ = MemoryLayout.ofStruct(
>>>          C_INT.withName("l2p_flags"),
>>>          C_LONG_LONG.withName("l2p_contigbytes"),
>>>          C_LONG_LONG.withName("l2p_devoffset")
>>>      ).withName("log2phys");
>>> ```
>>>
>>> During runtime, when the class was loaded and the VarHandle for "l2p_contigbytes" was created, I got the following exception:
>>>
>>> Exception in thread "main" java.lang.ExceptionInInitializerError
>>> 	at com.example.fuse_h$fuse_operations.$LAYOUT(fuse_h.java:14808)
>>> 	at com.example.fuse_h$fuse_operations.allocate(fuse_h.java:16294)
>>> 	...
>>> Caused by: java.lang.UnsupportedOperationException: Invalid alignment requirements for layout b64(l2p_contigbytes)[abi/kind=LONG_LONG,layout/name=l2p_contigbytes]
>>> 	at jdk.incubator.foreign/jdk.internal.foreign.LayoutPath.checkAlignment(LayoutPath.java:273)
>>> 	at jdk.incubator.foreign/jdk.internal.foreign.LayoutPath.dereferenceHandle(LayoutPath.java:159)
>>> 	at jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.lambda$varHandle$2(MemoryLayout.java:488)
>>> 	at jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.computePathOp(MemoryLayout.java:538)
>>> 	at jdk.incubator.foreign/jdk.incubator.foreign.MemoryLayout.varHandle(MemoryLayout.java:488)
>>> 	at com.example.fuse_h_constants_1.<clinit>(fuse_h_constants_1.java:1921)
>>> 	... 5 more
>>>
>>> I set a breakpoint at LayoutPath.checkAlignment and can tell that "l2p_contigbytes" has an offset of 32 bit (sounds reasonable) but an alignment of 64 bit. I have no idea, what all this means, but apparently it is invalid.
>>>
>>> I were able to avoid this error in my test project, but I thought I'd better report this in case there is something wrong, as I can see nothing special about aforementioned struct.
>>>
>>> Let me know if I can provide any further information!
>>>
>>> Sebastian


More information about the panama-dev mailing list