On Mon, 3 Mar 2025 12:22:01 GMT, Kevin Walls <kev...@openjdk.org> wrote:
> Following on from JDK-8350820, which backed out the _snprintf to snprintf > change (JDK-8336289) in OperatingSystemImpl.c on Windows, because the counter > names were being truncated (so CPU monitoring was not possible). > > This change moves to snprintf again, but the counter names are not truncated. > > snprintf must need the null terminator to fit inside the buffer length given. > It does not, and snprintf truncates (and always add the null terminator). In makeFullCounterPath(): We calculate a size (length of the counter in characters), which might be '\Process(java#0)% Processor Time', 33 chars. That size does not include the null terminator. We malloc a buffer of (size+1). Then we use the original size in the _snprintf. This has worked for years. But snprintf is slightly different. snprintf behaviour: https://en.cppreference.com/w/c/io/fprintf (including snprintf) "At most bufsz - 1 characters are written. The resulting character string will be terminated with a null character" That seems enough to say we have a problem. Although its wording could be clearer on whether "bufsz-1 characters" includes the null. https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170 "snprintf always stores a terminating NULL character, truncating the output if necessary." "The difference is that if you run out of buffer, snprintf null-terminates the end of the buffer and returns the number of characters that would have been required whereas _snprintf doesn't null-terminate the buffer and returns -1. Also, snprintf() includes one more character in the output because it doesn't null-terminate the buffer." (the last sentence quoted there seems to contradict the first) ----------------- Did we run out of buffer? snprintf called with a 33 char string and a buf len of 33, it won't have room for the null (there is room in the malloc'd buffer, but the len passed to snprintf does not include it). So it truncates and writes a null within the bounds it knows about. snprintf needs the null to fit inside the buffer length given. ------------- PR Comment: https://git.openjdk.org/jdk/pull/23861#issuecomment-2695039462