diff --git a/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c b/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c index 30fa8eea2069adb2f2968e03b817830123147080..b9f3428c1fa72a9cddb618127187999b962db7d7 100644 --- a/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c +++ b/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c @@ -89,25 +89,35 @@ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, } } - // Get buffer size needed to read all processes - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; - if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0) { - JNU_ThrowByNameWithLastError(env, - "java/lang/RuntimeException", "sysctl failed"); - return -1; - } + int errsysctl; + int maxRetries = 100; + void *buffer = NULL; + do { + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; + if (buffer != NULL) free(buffer); + // Get buffer size needed to read all processes + if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0) { + JNU_ThrowByNameWithMessageAndLastError(env, + "java/lang/RuntimeException", "sysctl failed"); + return -1; + } - // Allocate buffer big enough for all processes - void *buffer = malloc(bufSize); - if (buffer == NULL) { - JNU_ThrowOutOfMemoryError(env, "malloc failed"); - return -1; - } + // Allocate buffer big enough for all processes; add a little + // bit of space to be able to hold a few more proc infos + // for processes started right after the first sysctl call + buffer = malloc(bufSize + 4 * sizeof(struct kinfo_proc)); + if (buffer == NULL) { + JNU_ThrowOutOfMemoryError(env, "malloc failed"); + return -1; + } - // Read process info for all processes - if (sysctl(mib, 4, buffer, &bufSize, NULL, 0) < 0) { - JNU_ThrowByNameWithLastError(env, - "java/lang/RuntimeException", "sysctl failed"); + // Read process info for all processes + errsysctl = sysctl(mib, 4, buffer, &bufSize, NULL, 0); + } while (errsysctl < 0 && errno == ENOMEM && maxRetries-- > 0); + + if (errsysctl < 0) { + JNU_ThrowByNameWithMessageAndLastError(env, + "java/lang/RuntimeException", "sysctl failed to get info about all processes"); free(buffer); return -1; } diff --git a/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c b/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c index d53e88764c5892996bd7bb5a611b6cb7ebc48c2e..8b900dcf6f64f22f88bfc7af0ff881290e06705e 100644 --- a/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c +++ b/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c @@ -537,7 +537,7 @@ jint unix_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, * position integer as a filename. */ if ((dir = opendir("/proc")) == NULL) { - JNU_ThrowByNameWithLastError(env, + JNU_ThrowByNameWithMessageAndLastError(env, "java/lang/RuntimeException", "Unable to open /proc"); return -1; }