RFR: 8319875: Add macOS implementation for jcmd System.map [v2]

Thomas Stuefe stuefe at openjdk.org
Mon Dec 2 14:55:42 UTC 2024


On Thu, 14 Nov 2024 14:13:16 GMT, Simon Tooke <stooke at openjdk.org> wrote:

>> Hi @stooke,
>> 
>> nice. There are some aspects about the output that is surprising, though. I expect reserved-only memory to be mapped with MAP_NORESERVE and no access rights. I expect committed memory to be mapped without MAP_NORESERVE and write- or executable access.
>> 
>> - (G1) I only see one segment for JAVAHEAP. I would expect at least two, one reserved-only, one reserved and committed. Or did you precommit the heap (start JVM with -Xmx==-Xms)? Can you please test that with ParallelGC and without specifying Xms, we should see four java heap mappings side by side, for young and old gen, each with a committed part (rw) and a reserved part (not accessible). Like we do now for the CODE section. Please also countercheck that the address ranges are correct against the heap range (easiest, run jcmd .. VM.info and look for the Heap section, it tells you the address ranges).
>> - The 64K META and CLASS blocks confuse me. For one, they are too small. A Metaspace node is 64M sized. It can contain multiple committed and reserved sections, so typically spreads over multiple lines, but usually not many. Here (G1 file), I see many that are 64K in size, spanning in total just about 5MB. You can counter-check the META blocks with `jcmd .. VM.metaspace vslist` - it prints the virtual space node list at the start.
>> - Another thing that is strange is that the MEAT lines are not coalesced, though the properties displayed seem to be the same. But that can be the result of hidden properties being different.
>> 
>> Also, could you rename the OS-specific names to `[lowercase-something]`? The `[UPPERCASE]` names are easily confused with the uppercase NMT tags.
>> 
>> Thanks!
>
> Hello, @tstuefe , and thanks for your comments.  I'll address a few here while I work on the others.
> I have changed the os-specific names to lowercase, but I don't think it makes them stand out more.  The square brackets were intended to do that.  Might I change this back?
> 
> I think there is only one JAVAHEAP segment because due to an issue with my build[1] there was no CDS archive available.
> 
> I will look at the META and CLASS entries and see if there are hidden properties that I can surface, or if there's another reason for so many entries.
> 
> [1] I had given a target architecture to the configure command, which turned on cross-compiles (which disables CDS archive building) even when building on the target platform.

Hi @stooke !

> Hello, @tstuefe , and thanks for your comments. I'll address a few here while I work on the others. I have changed the os-specific names to lowercase, but I don't think it makes them stand out more. The square brackets were intended to do that. Might I change this back?

Sure, if it looks worse. I just wanted to make sure we can cleanly distinguish NMT sections from OS sections.

> 
> I think there is only one JAVAHEAP segment because due to an issue with my build[1] there was no CDS archive available.

Has nothing to do with CDS. The heap consists of committed and reserved areas. Committed areas have backing swap space allocated for them, and are accessible. Reserved areas have not and are generally not. API wise the difference is that Reserved sections set the MAP_NORESERVE flag for mmap, and are generally allocated with PROT_NONE. 

So, the heap should show up with several neighboring sections, some committed, some just reserved. Similar how most of the stacks should show up with two entries, one for the writable stack, one for the guard page that is protected.

---


Simple test I did on MacOS with your patch: I reserve 1G of memory at startup, uncommitted (added to os::init_2)


  if (UseNewCode) {
    char* p = os::reserve_memory(G, false, mtInternal);
    tty->print_cr("Pointer is %p", p);
  }



vmmap shows:


VM_ALLOCATE                 10ccb4000-14ccb4000    [  1.0G     0K     0K     0K] ---/rwx SM=NUL  


so, looks good. 1GB, with all protection flags cleared. But System.map shows nothing for this address range.


Now, I commit the second half of the range:



  if (UseNewCode) {
    char* p = os::reserve_memory(G, false, mtInternal);
    tty->print_cr("Pointer is %p", p);
    bool b = os::commit_memory(p + (512 * M), 512 * M, false);
    assert(b,"???");
  }


vmmap shows only the committed part now, omitting the still uncommitted first half. But it gets the protection flags right again (rw now):


VM_ALLOCATE (reserved)      148000000-168000000    [512.0M     0K     0K     0K] rw-/rwx SM=NUL          reserved VM address space (unallocated)


System.map shows nothing.


What goes on? Is the OS lying to us? Do we have an error? Both vmmap and System.map seem to struggle, with vmmap being somewhat more correct.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/20953#issuecomment-2511753610


More information about the serviceability-dev mailing list