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 //