src/os/linux/vm/os_linux.cpp
Print this page
*** 101,110 ****
--- 101,111 ----
# include <sys/shm.h>
# include <link.h>
# include <stdint.h>
# include <inttypes.h>
# include <sys/ioctl.h>
+ # include <sys/prctl.h>
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
// getrusage() is prepared to handle the associated failure.
*** 5995,6011 ****
}
// Get the default path to the core file
// Returns the length of the string
int os::get_core_path(char* buffer, size_t bufferSize) {
! const char* p = get_current_directory(buffer, bufferSize);
if (p == NULL) {
assert(p != NULL, "failed to get current directory");
return 0;
}
return strlen(buffer);
}
#ifdef JAVASE_EMBEDDED
//
--- 5996,6149 ----
}
// Get the default path to the core file
// Returns the length of the string
int os::get_core_path(char* buffer, size_t bufferSize) {
! /*
! * Max length of /proc/sys/kernel/core_pattern is 128 characters.
! * See https://www.kernel.org/doc/Documentation/sysctl/kernel.txt
! */
! const int core_pattern_len = 129;
! char core_pattern[core_pattern_len] = {0};
!
! FILE *core_pattern_file = fopen("/proc/sys/kernel/core_pattern", "r");
! if (core_pattern_file != NULL) {
! char *ret_ptr = fgets(core_pattern, core_pattern_len, core_pattern_file);
! fclose(core_pattern_file);
!
! if (ret_ptr != NULL) {
! char *last_char = core_pattern + strlen(core_pattern) - 1;
! if (*last_char == '\n') {
! *last_char = '\0';
! }
! }
!
! }
!
! if (strlen(core_pattern) == 0) {
! return 0;
! }
!
! // Get executable path for '%e' and '%E'
! char exe_path[PATH_MAX] = {0};
! readlink("/proc/self/exe", exe_path, PATH_MAX);
!
! char core_path[PATH_MAX] = {0};
! bool with_pid = false;
! size_t n = 0;
! char *core_pattern_seq = core_pattern;
! while (*core_pattern_seq) {
!
! if (*core_pattern_seq == '%') {
! int written = 0;
! core_pattern_seq++; // Get format character
!
! switch (*core_pattern_seq) {
!
! case '\0': // NULL termination
! break;
!
! case '%': // double percent
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%%");
! break;
!
! case 'p': // pid
! with_pid = true;
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%d", current_process_id());
! break;
!
! case 'u': // uid
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%d", getuid());
! break;
!
! case 'g': // gid
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%d", getgid());
! break;
!
! case 'd': // dump mode
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%d",
! prctl(PR_GET_DUMPABLE, NULL, NULL, NULL, NULL));
! break;
!
! case 'h': // hostname
! struct utsname un;
! uname(&un); // This call will be succeeded.
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%s", un.nodename);
! break;
!
! case 'e': // executable filename (shorten)
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%s", basename(exe_path));
! break;
!
! case 'E': // executable filename (path)
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%s", exe_path);
! break;
!
! case 'c': // core limit size
! struct rlimit rlim;
! getrlimit(RLIMIT_CORE, &rlim); // Calling getrlimit() to myself will be succeeded.
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%lu", rlim.rlim_cur);
! break;
!
! /*
! * We cannot other values.
! * e.g. 'P' (global pid), 's' (signal), 't' (UNIX time of dump)
! *
! * - 't' will set to core dump time in Linux kernel.
! * Thus we cannot set it in this function.
! * - If user set undefined character, Linux kernel will drop it.
! * We remain it because Linux kernel may define it in the future.
! */
! default:
! written = jio_snprintf(&core_path[n], PATH_MAX - n, "%%%c", *core_pattern_seq);
! break;
!
! }
!
! n += written;
! } else {
! core_path[n] = *core_pattern_seq;
! n++;
! }
!
! core_pattern_seq++; // Get next character
! }
!
! if (!with_pid && (core_path[0] != '|')) {
! char val[2] = {0};
! FILE *core_uses_pid_file = fopen("/proc/sys/kernel/core_uses_pid", "r");
! if (core_uses_pid_file != NULL) {
! fgets(val, 2, core_uses_pid_file);
! fclose(core_uses_pid_file);
! }
!
! if (val[0] == '1') {
! jio_snprintf(&core_path[n], PATH_MAX - n, ".%d", current_process_id());
! }
!
! }
!
! if (core_path[0] == '/') {
! jio_snprintf(buffer, bufferSize, core_path);
! } else {
! char cwd[PATH_MAX];
! const char* p = get_current_directory(cwd, PATH_MAX);
if (p == NULL) {
assert(p != NULL, "failed to get current directory");
return 0;
}
+ if (core_path[0] == '|') {
+ jio_snprintf(buffer, bufferSize, "\"%s\" (or dumping to %s/core.%d)",
+ &core_path[1], p, current_process_id());
+ } else {
+ jio_snprintf(buffer, bufferSize, "%s/%s", p, core_path);
+ }
+
+ }
+
return strlen(buffer);
}
#ifdef JAVASE_EMBEDDED
//