mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-17 19:33:18 +00:00
8359706: Add file descriptor count to VM.info
Reviewed-by: kevinw, stuefe
This commit is contained in:
parent
a1e4621b30
commit
b0831572e2
@ -2667,3 +2667,7 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}
|
||||
void os::jfr_report_memory_info() {}
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
void os::print_open_file_descriptors(outputStream* st) {
|
||||
// File descriptor counting not implemented on AIX
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@
|
||||
# include <fcntl.h>
|
||||
# include <fenv.h>
|
||||
# include <inttypes.h>
|
||||
# include <mach/mach.h>
|
||||
# include <poll.h>
|
||||
# include <pthread.h>
|
||||
# include <pwd.h>
|
||||
@ -102,6 +103,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <libproc.h>
|
||||
#include <mach/task_info.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
@ -2596,3 +2598,45 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
|
||||
|
||||
return res;
|
||||
} // end: os::pd_dll_unload()
|
||||
|
||||
void os::print_open_file_descriptors(outputStream* st) {
|
||||
#ifdef __APPLE__
|
||||
char buf[1024 * sizeof(struct proc_fdinfo)];
|
||||
os::Bsd::print_open_file_descriptors(st, buf, sizeof(buf));
|
||||
#else
|
||||
st->print_cr("Open File Descriptors: unknown");
|
||||
#endif
|
||||
}
|
||||
|
||||
void os::Bsd::print_open_file_descriptors(outputStream* st, char* buf, size_t buflen) {
|
||||
#ifdef __APPLE__
|
||||
pid_t my_pid;
|
||||
|
||||
// ensure the scratch buffer is big enough for at least one FD info struct
|
||||
assert(buflen >= sizeof(struct proc_fdinfo));
|
||||
kern_return_t kres = pid_for_task(mach_task_self(), &my_pid);
|
||||
if (kres != KERN_SUCCESS) {
|
||||
st->print_cr("Open File Descriptors: unknown");
|
||||
return;
|
||||
}
|
||||
size_t max_fds = buflen / sizeof(struct proc_fdinfo);
|
||||
struct proc_fdinfo* fds = reinterpret_cast<struct proc_fdinfo*>(buf);
|
||||
|
||||
// fill our buffer with FD info, up to the available buffer size
|
||||
int res = proc_pidinfo(my_pid, PROC_PIDLISTFDS, 0, fds, max_fds * sizeof(struct proc_fdinfo));
|
||||
if (res <= 0) {
|
||||
st->print_cr("Open File Descriptors: unknown");
|
||||
return;
|
||||
}
|
||||
|
||||
// print lower threshold if count exceeds buffer size
|
||||
int nfiles = res / sizeof(struct proc_fdinfo);
|
||||
if ((size_t)nfiles >= max_fds) {
|
||||
st->print_cr("Open File Descriptors: > %zu", max_fds);
|
||||
return;
|
||||
}
|
||||
st->print_cr("Open File Descriptors: %d", nfiles);
|
||||
#else
|
||||
st->print_cr("Open File Descriptors: unknown");
|
||||
#endif
|
||||
}
|
||||
@ -123,6 +123,8 @@ class os::Bsd {
|
||||
static int get_node_by_cpu(int cpu_id);
|
||||
|
||||
static void print_uptime_info(outputStream* st);
|
||||
static void print_open_file_descriptors(outputStream* st, char* buf, size_t buflen);
|
||||
static void print_open_file_descriptors(outputStream* st);
|
||||
};
|
||||
|
||||
#endif // OS_BSD_OS_BSD_HPP
|
||||
|
||||
@ -83,6 +83,7 @@
|
||||
#endif
|
||||
|
||||
# include <ctype.h>
|
||||
# include <dirent.h>
|
||||
# include <dlfcn.h>
|
||||
# include <endian.h>
|
||||
# include <errno.h>
|
||||
@ -113,6 +114,7 @@
|
||||
# include <sys/types.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <syscall.h>
|
||||
# include <time.h>
|
||||
# include <unistd.h>
|
||||
#ifdef __GLIBC__
|
||||
# include <malloc.h>
|
||||
@ -2161,6 +2163,8 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
os::Posix::print_rlimit_info(st);
|
||||
|
||||
os::print_open_file_descriptors(st);
|
||||
|
||||
os::Posix::print_load_average(st);
|
||||
st->cr();
|
||||
|
||||
@ -5429,3 +5433,33 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
|
||||
|
||||
return res;
|
||||
} // end: os::pd_dll_unload()
|
||||
|
||||
void os::print_open_file_descriptors(outputStream* st) {
|
||||
DIR* dirp = opendir("/proc/self/fd");
|
||||
int fds = 0;
|
||||
struct dirent* dentp;
|
||||
const jlong TIMEOUT_NS = 50000000L; // 50 ms in nanoseconds
|
||||
bool timed_out = false;
|
||||
|
||||
// limit proc file read to 50ms
|
||||
jlong start = os::javaTimeNanos();
|
||||
assert(dirp != nullptr, "No proc fs?");
|
||||
while ((dentp = readdir(dirp)) != nullptr && !timed_out) {
|
||||
if (isdigit(dentp->d_name[0])) fds++;
|
||||
if (fds % 100 == 0) {
|
||||
jlong now = os::javaTimeNanos();
|
||||
if ((now - start) > TIMEOUT_NS) {
|
||||
timed_out = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
if (timed_out) {
|
||||
st->print_cr("Open File Descriptors: > %d", fds);
|
||||
} else {
|
||||
st->print_cr("Open File Descriptors: %d", fds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6276,6 +6276,10 @@ const void* os::get_saved_assert_context(const void** sigInfo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void os::print_open_file_descriptors(outputStream* st) {
|
||||
// File descriptor counting not supported on Windows.
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows/x64 does not use stack frames the way expected by Java:
|
||||
* [1] in most cases, there is no frame pointer. All locals are addressed via RSP
|
||||
|
||||
@ -893,6 +893,9 @@ class os: AllStatic {
|
||||
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
|
||||
static void print_elapsed_time(outputStream* st, double time);
|
||||
|
||||
// Prints the number of open file descriptors for the current process
|
||||
static void print_open_file_descriptors(outputStream* st);
|
||||
|
||||
static void print_user_info(outputStream* st);
|
||||
static void print_active_locale(outputStream* st);
|
||||
|
||||
|
||||
@ -1329,6 +1329,13 @@ void VMError::report(outputStream* st, bool _verbose) {
|
||||
STEP_IF("printing OS information", _verbose)
|
||||
os::print_os_info(st);
|
||||
st->cr();
|
||||
#ifdef __APPLE__
|
||||
// Avoid large stack allocation on Mac for FD count during signal-handling.
|
||||
os::Bsd::print_open_file_descriptors(st, buf, sizeof(buf));
|
||||
st->cr();
|
||||
#else
|
||||
os::print_open_file_descriptors(st);
|
||||
#endif
|
||||
|
||||
STEP_IF("printing CPU info", _verbose)
|
||||
os::print_cpu_info(st, buf, sizeof(buf));
|
||||
@ -1550,6 +1557,8 @@ void VMError::print_vm_info(outputStream* st) {
|
||||
|
||||
os::print_os_info(st);
|
||||
st->cr();
|
||||
os::print_open_file_descriptors(st);
|
||||
st->cr();
|
||||
|
||||
// STEP("printing CPU info")
|
||||
|
||||
|
||||
@ -33,7 +33,6 @@ import java.util.List;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -182,5 +181,10 @@ public class TestJcmdSanity {
|
||||
output.shouldNotContain("*** Handler was modified!");
|
||||
output.shouldNotContain("*** Expected: "); // e.g. *** Expected: javaSignalHandler in ...
|
||||
}
|
||||
|
||||
// Should find file descriptor counting on Mac and Linux
|
||||
if (Platform.isLinux() || Platform.isOSX()) {
|
||||
output.shouldMatch("Open File Descriptors: \\d+");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user