Can access closed memory segment

Jorn Vernee jorn.vernee at oracle.com
Tue Jun 18 11:18:58 UTC 2024


 > when closing the scope the VM only checks if the arena is on stack 
but the memory segment can be stored in a static final.

I think you're talking about the handshake that we run when closing a 
shared arena? Note that in that code we only care about a thread that is 
currently in the process of accessing a memory segment, in which case 
the arena /has/ the be on the stack (or rather, it's a local variable).

The way shared closure works is: 1. set the arena's liveness state to 
closed. 2. submit a thread-local handshake to all threads. 2a. walk each 
thread stack a maximum of 10 frames, or until we find a method marked 
with @Scoped 2b. for methods marked @Scoped only, look inside the local 
variables of those frames to see if we find the arena we're closing. 2c. 
if we find it, install an async exception on that thread, which gets 
thrown as soon as the target thread continues running. 3. free memory.

As a result: - because of the handshake, all threads will see the 
updated liveness state of the shared arena that we set in (1) above. - 
threads that were not accessing the arena, but try to in the future, 
will see the up-to-date closed state and throw. - threads that were 
accessing the arena (i.e. when they were stopped by the handshake, they 
were somewhere//in the code /after/ checking the liveness state, but 
/before/ doing the actual access), will throw the async exception, 
preventing them from ever doing the actual access.

We have a stress test in test/jdk/java/foreign/TestHandshake.java which 
has helped to catch quite a few obscure issues. If you think there's 
still an issue, I suggest trying to modify that test to try to reproduce it.

Jorn

On 18-6-2024 09:54, Remi Forax wrote:
> Hello,
> I think i've found an issue in the current implementation of shared arena close(),
> when closing the scope the VM only checks if the arena is on stack but the memory segment can be stored in a static final.
>
> In the following code, i'm able to read the segment after the shared arena is closed.
>
> public class SharedArenaCloseBug {
>    static final Arena SHARED = Arena.ofShared();
>    static final MemorySegment SEGMENT = SHARED.allocate(16);
>    static int STATE;
>
>    void run() {
>      for(;;) {
>        if (STATE == 0) {
>          var value = SEGMENT.get(ValueLayout.JAVA_BYTE, 0L);
>          if (value == 42) {
>            return;
>          }
>        }
>      }
>    }
>
>    public static void main(String[] args) throws InterruptedException {
>      var bug = new SharedArenaCloseBug();
>      var thread = new Thread(bug::run);
>      thread.start();
>      Thread.sleep(100);
>      STATE = 1;
>      System.out.println("state 1");
>      Thread.sleep(100);
>      System.out.println("close");
>      SEGMENT.set(ValueLayout.JAVA_BYTE, 0L, (byte) 42);
>      SHARED.close();
>      Thread.sleep(100);
>      System.out.println("state 0");
>      STATE = 0;
>      Thread.sleep(100);
>      System.out.println("join");
>      thread.join();
>    }
> }
>
> regards,
> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20240618/0b28e7ad/attachment.htm>


More information about the panama-dev mailing list