Hacker News new | ask | show | jobs
by CharlesW 821 days ago
> "As a normal part of the just-in-time compile and execute cycle, processes running on macOS may access memory in protected memory regions."

I'm just a lowly JavaScript/TypeScript/PHP programmer, but what is the Very Good Reason that Java trying to access other processes' memory?

6 comments

I don’t think the article claims that a Java process tries to access some other process’s memory.

In a typical modern operating system, a memory page can be non-writable and non-executable, writable and non-executable, or non-writable and executable, but not simultaneously writable AND executable.

If you generate executable code at runtime, then you need write access to a page to write the executable code into that page. Then you need to tell the operating system to change the page from writable to executable.

If you then try to write to the page, you’ll get a signal (SIGSEGV or SIGBUS, according to the article).

Oracle’s JVM apparently relies on this behavior: a Java process sometimes tries to write to a page (in its own memory space) that is not marked writable. The JVM then catches the SIGSEGV and recovers (perhaps by asking the operating system to change the page back from executable to writable, or by arranging to write to a different page, or to abort the write operation altogether).

Thank you, that explained it way better than the original link.
It's not. It's trying to access unmapped or protected memory in its own process.

Basically what its used for is to implement an 'if' that's super fast on the most likely path but super slow on the less likely path.

It's not super clear what its being used for (this is often used for the GC but the fact that graal isn't affected means that likely still works). Possibly they are using this to detect attempts to use inline-cache entries that have been deleted.

object.field is implemented as a direct load from the object; if the object turned out to be null, then the resultant signal is caught and turned into a NullPointerException
sorry, I didn't read the linked post closely enough—from my reading, this case is not one of the ones that was broken
In a virtual memory operating system, every program has its own address space. Accessing an unmapped address is not the same as trying to access another process's memory.

It's also pretty common to use memory protection to autoextend stacks... Allocate the stack size you need, ask the OS to mark the page(s) after the stack as protected, catch the signal when you hit the protection, allocate some more stack and a new protected page unless the stack is too big. Works for heaps too.

Let the MMU hardware check accesses, so you don't have to check everything in software all the time.

It depends on exactly what is being done.

A fairly common idiom is to use memory protection to provide zero cost access checks, as you can generally catch the signals produced by most memory faults, and then work out where things went wrong and convert the memory access error into a catchable exception, or to lazily construct data structures or code.

So you want the trap, but the trap itself can be handled. It sounds like there’s been a semantic change when the trap occurs for execution of an address or an access to an executable page.

There are also a bunch of poorly documented Mac APIs to inform the memory manager and linker about JIT regions and I wonder if it’s related to those. It really depends on exactly what oracle’s jvm is trying to do, and what the subsequent cause of the fault is.

Certainly it’s a less than optimal failure though :-/

The reasons are literally spelled out in the following paragraphs.
I’m asking because the reasons seem dumb to me, which is why I’m asking people smarter than I am about low-level memory management if they’re legitimate.
JIT compilation can happen at any time. The runtime wants to create a native version of a previously interpreted snippet of code when it is called frequently enough to warrant this.

The article also describes W^X functionality, which means a region of memory is either executable (x)or writable. On macOS 14.4 violating this either-or condition results in a signal that can not be handled by the process.

The article doesnt say anything about the JVM accessing other processes memory though.
Accessing such areas is sometimes done deliberately since programmers could rely on the OS telling them what just happened using signals instead of nuking the process wholesale. Doing it without signals is usually slow and/or clunky (null-pointer checks, read/write permissions, existence of pages), or straight out impossible.

Accessing other processes' memory is not the concern since virtual memory provides each process the illusion of having the entire address space for itself.