From 17ef8a44a90a74724508a91abda3686e5123d1cd Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 26 May 2023 10:51:39 +0000 Subject: [PATCH] 8299665: /proc/self/stat parsing in libmanagement broken by execname with spaces Reviewed-by: sspitsyn, amenkov --- .../libmanagement_ext/UnixOperatingSystem.c | 24 ++++++++++++++- .../native/libmanagement_ext/management_ext.c | 7 +++++ .../native/libmanagement_ext/management_ext.h | 2 ++ .../libmanagement_ext/OperatingSystemImpl.c | 30 +++---------------- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c b/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c index a328cd5818c..af7d52424b7 100644 --- a/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c +++ b/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,8 @@ #include #include #include + +#include "management_ext.h" #include "com_sun_management_internal_OperatingSystemImpl.h" #include @@ -331,6 +333,26 @@ double get_process_load() { return u + s; } +static long read_vmem_usage(const char *procfile, unsigned long *vsize) { + int n = read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", vsize); + if (n != 1) { + return -1; + } else { + return *vsize; + } +} + +JNIEXPORT jlong JNICALL +Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 + (JNIEnv *env, jobject mbean) +{ + unsigned long vsize; + if (read_vmem_usage("/proc/self/stat", &vsize) == -1) { + throw_internal_error(env, "Unable to get virtual memory usage"); + } + return (jlong) vsize; +} + JNIEXPORT jdouble JNICALL Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 (JNIEnv *env, jobject dummy) diff --git a/src/jdk.management/share/native/libmanagement_ext/management_ext.c b/src/jdk.management/share/native/libmanagement_ext/management_ext.c index 88925af2c82..a6d733b6256 100644 --- a/src/jdk.management/share/native/libmanagement_ext/management_ext.c +++ b/src/jdk.management/share/native/libmanagement_ext/management_ext.c @@ -35,6 +35,13 @@ const JmmInterface* jmm_interface_management_ext = NULL; static JavaVM* jvm = NULL; jint jmm_version_management_ext = 0; +void throw_internal_error(JNIEnv* env, const char* msg) { + char errmsg[128]; + + snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg); + JNU_ThrowInternalError(env, errmsg); +} + JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* env; diff --git a/src/jdk.management/share/native/libmanagement_ext/management_ext.h b/src/jdk.management/share/native/libmanagement_ext/management_ext.h index d80c70122c7..415377fb335 100644 --- a/src/jdk.management/share/native/libmanagement_ext/management_ext.h +++ b/src/jdk.management/share/native/libmanagement_ext/management_ext.h @@ -37,4 +37,6 @@ extern const JmmInterface* jmm_interface_management_ext; extern jint jmm_version_management_ext; +void throw_internal_error(JNIEnv* env, const char* msg); + #endif diff --git a/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c b/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c index 75b00ce9a64..3183d8ef9a1 100644 --- a/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c +++ b/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c @@ -82,13 +82,6 @@ static jlong page_size = 0; #define closedir closedir64 #endif -static void throw_internal_error(JNIEnv* env, const char* msg) { - char errmsg[128]; - - snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg); - JNU_ThrowInternalError(env, errmsg); -} - // true = get available swap in bytes // false = get total swap in bytes static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) { @@ -129,29 +122,13 @@ Java_com_sun_management_internal_OperatingSystemImpl_initialize0 page_size = sysconf(_SC_PAGESIZE); } +// Linux-specific implementation is in UnixOperatingSystem.c +#if !defined(__linux__) JNIEXPORT jlong JNICALL Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 (JNIEnv *env, jobject mbean) { -#if defined(__linux__) - FILE *fp; - unsigned long vsize = 0; - - if ((fp = fopen("/proc/self/stat", "r")) == NULL) { - throw_internal_error(env, "Unable to open /proc/self/stat"); - return -1; - } - - // Ignore everything except the vsize entry - if (fscanf(fp, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", &vsize) == EOF) { - throw_internal_error(env, "Unable to get virtual memory usage"); - fclose(fp); - return -1; - } - - fclose(fp); - return (jlong)vsize; -#elif defined(__APPLE__) +#if defined(__APPLE__) struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; @@ -168,6 +145,7 @@ Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySi return (64 * MB); #endif } +#endif JNIEXPORT jlong JNICALL Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0