8339487: ProcessHandleImpl os_getChildren sysctl call - retry in case of ENOMEM and enhance exception message

Reviewed-by: alanb, lucy, rriggs
This commit is contained in:
Matthias Baesken 2024-09-09 07:35:18 +00:00
parent cb5c60b530
commit 4ff72dc57e
2 changed files with 28 additions and 18 deletions

View File

@ -97,25 +97,35 @@ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray,
} }
} }
// Get buffer size needed to read all processes int errsysctl;
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; int maxRetries = 100;
if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0) { void *buffer = NULL;
JNU_ThrowByNameWithLastError(env, do {
"java/lang/RuntimeException", "sysctl failed"); int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
return -1; 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 // Allocate buffer big enough for all processes; add a little
void *buffer = malloc(bufSize); // bit of space to be able to hold a few more proc infos
if (buffer == NULL) { // for processes started right after the first sysctl call
JNU_ThrowOutOfMemoryError(env, "malloc failed"); buffer = malloc(bufSize + 4 * sizeof(struct kinfo_proc));
return -1; if (buffer == NULL) {
} JNU_ThrowOutOfMemoryError(env, "malloc failed");
return -1;
}
// Read process info for all processes // Read process info for all processes
if (sysctl(mib, 4, buffer, &bufSize, NULL, 0) < 0) { errsysctl = sysctl(mib, 4, buffer, &bufSize, NULL, 0);
JNU_ThrowByNameWithLastError(env, } while (errsysctl < 0 && errno == ENOMEM && maxRetries-- > 0);
"java/lang/RuntimeException", "sysctl failed");
if (errsysctl < 0) {
JNU_ThrowByNameWithMessageAndLastError(env,
"java/lang/RuntimeException", "sysctl failed to get info about all processes");
free(buffer); free(buffer);
return -1; return -1;
} }

View File

@ -528,7 +528,7 @@ jint unix_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray,
* position integer as a filename. * position integer as a filename.
*/ */
if ((dir = opendir("/proc")) == NULL) { if ((dir = opendir("/proc")) == NULL) {
JNU_ThrowByNameWithLastError(env, JNU_ThrowByNameWithMessageAndLastError(env,
"java/lang/RuntimeException", "Unable to open /proc"); "java/lang/RuntimeException", "Unable to open /proc");
return -1; return -1;
} }