Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down