On Thu, 15 Aug 2024 13:45:16 GMT, Simon Tooke <sto...@openjdk.org> wrote:

> This is a port of [JDK-8318636](https://github.com/openjdk/jdk/pull/16301) to 
> Windows.
> 
> System.map and System.dump_map are implemented using the Windows API and 
> provide roughly the same information in the same format.  Most of the heavy 
> lifting was implemented by @tstuefe in #16301 - this PR adds the Windows 
> implementation and enables the common code for Windows 64 bit.
>  
> [Sample output (with NMT 
> enabled)](https://github.com/user-attachments/files/16663332/vm_memory_map_760.txt)

Hi Simon,

this is nice, thank you!

Mostly nits.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 3:

> 1: /*
> 2:  * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights 
> reserved.
> 3:  * Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates.

New files are added with the current copyright year, unless they are the result 
of moving.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 32:

> 30: 
> 31: #include <limits>
> 32: #include <iostream>

Please use C-headers. We only use C++ headers sparingly. Why do you include 
these headers?

src/hotspot/os/windows/memMapPrinter_windows.cpp line 63:

> 61:     }
> 62: 
> 63:     const char* getProtectString(char* buffer, size_t bufsiz, DWORD prot) 
> {

Style: In hotspot we use camel case for classes, lower_case_underscore for 
method, functions etc.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 69:

> 67:         const int IP = 3;
> 68:         int idx = 4;
> 69:         strncpy_s(buffer, bufsiz, "----  ", 7);

We tend to use os::snprintf or jio_snprintf for this. I find strncpy_s a bit 
fragile since one needs to update both string literal and char count when 
changing things.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 98:

> 96:             buffer[idx++] = 'n';
> 97:         } else if (prot != 0) {
> 98:             snprintf(buffer, bufsiz, "(0x%x)", prot);

This could truncate for the longest possible value (16+4 chars).

src/hotspot/os/windows/memMapPrinter_windows.cpp line 111:

> 109:             buffer[idx++] = 'W';
> 110:         }
> 111:         buffer[idx] = 0;

Please give us an assert here for idx < bufsiz

src/hotspot/os/windows/memMapPrinter_windows.cpp line 114:

> 112:         return buffer;
> 113:     }
> 114:     const char* getStateString(char* buffer, size_t bufsiz, 
> MEMORY_BASIC_INFORMATION& mInfo) {

We have a utility class for printing to a limited buffer (stringStream). It 
takes care of buffer limits and zero termination for you. I would use that one 
where possible.


stringStream ss(buffer, bufsiz);
if (mInfo.State == MEM_COMMIT) {
  ss.put('c');
}
...
else { ss.print("0x%x", mInfo.State); }
return buffer;

src/hotspot/os/windows/memMapPrinter_windows.cpp line 145:

> 143:   size_t _total_region_size;  // combined resident set size
> 144:   size_t _total_committed;    // combined committed size
> 145:   size_t _total_reserved;     // combined shared size

I would like us to be careful with terminology since that can get confusing 
quickly when jumping between OS code and generic code. 

In hotspot terminology, "reserved" are parts of the address space that have 
been allocated for the process, *regardless of commit state*. So, the whole 
region would count as "reserved", with some pages being also committed, and 
some not. But on Windows, the MEM_RESERVE state is only given to uncommitted 
regions, so there is a subtle difference.

I would circumvent the problem by counting only:
- total size (as in sum of region sizes that are not MEM_FREE)
- committed size (as in sum of region sizes that are MEM_COMMIT)

src/hotspot/os/windows/memMapPrinter_windows.cpp line 162:

> 160:     outputStream* st = session.out();
> 161:     os::print_os_info(st);
> 162:     os::print_memory_info(st);

The "danger" here is that both of these functions may bloat in the future and 
print a lot more than today; and that we may want to use this printout in 
places where we also print out OS info and memory info, and therefore get 
duplicated printout (e.g. hs-err printing or jcmd VM.info). 

But I would print out the number of mappings you counted, and the total size of 
committed regions.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 243:

> 241:     printer.print_header();
> 242: 
> 243:     MEMORY_BASIC_INFORMATION mInfo;

Just to be sure, I would zero out mInfo.

src/hotspot/os/windows/memMapPrinter_windows.cpp line 246:

> 244:     MappingInfo info;
> 245: 
> 246:     for (char* ptr = 0; VirtualQueryEx(hProcess, ptr, &mInfo, 
> sizeof(mInfo)) == sizeof(mInfo); ptr += mInfo.RegionSize) {

I would add a failsafe breakout in case we made a thinking error somewhere or 
the address space is insanely fragmented. Maybe break out after a million 
regions? Or, after a certain time (e.g. 10 seconds). I also would assert for 
RegionSize > 0

src/hotspot/share/services/diagnosticCommand.cpp line 1207:

> 1205:     const char* absname = os::Posix::realpath(name, tmp, sizeof(tmp));
> 1206:     name = absname != nullptr ? absname : name;
> 1207: #endif

I wince a bit a the new ifdefs. Possibly for a separate RFE, it would be nice 
to have a function os::realpath() that uses realpath(2) on POSIX platforms, 
_fullpath on Windows.

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

PR Review: https://git.openjdk.org/jdk/pull/20597#pullrequestreview-2247042750
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722735615
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722743452
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722745964
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722766129
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722763766
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722757477
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722770690
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722783949
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722795939
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722809524
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722807479
PR Review Comment: https://git.openjdk.org/jdk/pull/20597#discussion_r1722801573

Reply via email to