--- old/src/share/vm/utilities/vmError.hpp 2015-07-17 15:15:09.550226134 -0400 +++ new/src/share/vm/utilities/vmError.hpp 2015-07-17 15:15:07.472254908 -0400 @@ -89,6 +89,9 @@ static void print_stack_trace(outputStream* st, JavaThread* jt, char* buf, int buflen, bool verbose = false); + static const char* gc_mode(); + static void print_oom_reasons(outputStream* st); + // accessor const char* message() const { return _message; } const char* detail_msg() const { return _detail_msg; } --- old/src/os/bsd/vm/os_bsd.cpp 2015-07-17 15:15:09.897591160 -0400 +++ new/src/os/bsd/vm/os_bsd.cpp 2015-07-17 15:15:08.756801753 -0400 @@ -1600,24 +1600,6 @@ return dlsym(handle, name); } - -static bool _print_ascii_file(const char* filename, outputStream* st) { - int fd = ::open(filename, O_RDONLY); - if (fd == -1) { - return false; - } - - char buf[32]; - int bytes; - while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { - st->print_raw(buf, bytes); - } - - ::close(fd); - - return true; -} - int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) { outputStream * out = (outputStream *) param; out->print_cr(PTR_FORMAT " \t%s", base_address, name); @@ -1678,15 +1660,38 @@ #endif } -void os::print_os_info_brief(outputStream* st) { - st->print("Bsd"); +void os::get_summary_os_info(char* buf, size_t buflen) { + // These buffers are small because we want this to be brief + // and not use a lot of stack while generating the hs_err file. + char os[100]; + size_t size = sizeof(os); + int mib_kern[] = { CTL_KERN, KERN_OSTYPE }; + if (sysctl(mib_kern, 2, os, &size, NULL, 0) < 0) { +#ifdef __APPLE__ + strncpy(os, "Darwin", sizeof(os)); +#elif __OpenBSD__ + strncpy(os, "OpenBSD", sizeof(os)); +#else + strncpy(os, "BSD", sizeof(os)); +#endif + } + char release[100]; + size = sizeof(release); + int mib_release[] = { CTL_KERN, KERN_OSRELEASE }; + if (sysctl(mib_release, 2, release, &size, NULL, 0) < 0) { + // if error, leave blank + strncpy(release, "", sizeof(release)); + } + snprintf(buf, buflen, "%s %s", os, release); +} + +void os::print_os_info_brief(outputStream* st) { os::Posix::print_uname_info(st); } void os::print_os_info(outputStream* st) { st->print("OS:"); - st->print("Bsd"); os::Posix::print_uname_info(st); @@ -1699,6 +1704,37 @@ // Nothing to do for now. } +void os::get_summary_cpu_info(char* buf, size_t buflen) { + unsigned int mhz; + size_t size = sizeof(mhz); + int mib[] = { CTL_HW, HW_CPU_FREQ }; + if (sysctl(mib, 2, &mhz, &size, NULL, 0) < 0) { + mhz = 0; + } + mhz /= 1000000; // reported in millions + + char model[100]; + size = sizeof(model); + int mib_model[] = { CTL_HW, HW_MODEL }; + if (sysctl(mib_model, 2, model, &size, NULL, 0) < 0) { + strncpy(model, cpu_arch, sizeof(model)); + } + + char machine[100]; + size = sizeof(machine); + int mib_machine[] = { CTL_HW, HW_MACHINE }; + if (sysctl(mib_machine, 2, machine, &size, NULL, 0) < 0) { + strncpy(machine, "", sizeof(machine)); + } + + if (mhz != 0) { + snprintf(buf, buflen, "%s %s %d MHz", model, machine, mhz); + } else { + // Don't report zero MHz + snprintf(buf, buflen, "%s %s", model, machine); + } +} + void os::print_memory_info(outputStream* st) { st->print("Memory:"); @@ -1709,11 +1745,6 @@ st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); st->cr(); - - // meminfo - st->print("\n/proc/meminfo:\n"); - _print_ascii_file("/proc/meminfo", st); - st->cr(); } void os::print_siginfo(outputStream* st, void* siginfo) { --- old/src/os/linux/vm/os_linux.cpp 2015-07-17 15:15:09.550608264 -0400 +++ new/src/os/linux/vm/os_linux.cpp 2015-07-17 15:15:07.692841562 -0400 @@ -2043,31 +2043,94 @@ // Searching for the debian_version file is the last resort. It contains // an informative string like "6.0.6" or "wheezy/sid". Because of this // "Debian " is printed before the contents of the debian_version file. + +const char* distro_files[] = { + "/etc/oracle-release", + "/etc/mandriva-release", + "/etc/mandrake-release", + "/etc/sun-release", + "/etc/redhat-release", + "/etc/lsb-release", + "/etc/SuSE-release", + "/etc/turbolinux-release", + "/etc/gentoo-release", + "/etc/ltib-release", + "/etc/angstrom-version", + "/etc/system-release", + "/etc/os-release", + NULL }; + void os::Linux::print_distro_info(outputStream* st) { - if (!_print_ascii_file("/etc/oracle-release", st) && - !_print_ascii_file("/etc/mandriva-release", st) && - !_print_ascii_file("/etc/mandrake-release", st) && - !_print_ascii_file("/etc/sun-release", st) && - !_print_ascii_file("/etc/redhat-release", st) && - !_print_ascii_file("/etc/lsb-release", st) && - !_print_ascii_file("/etc/SuSE-release", st) && - !_print_ascii_file("/etc/turbolinux-release", st) && - !_print_ascii_file("/etc/gentoo-release", st) && - !_print_ascii_file("/etc/ltib-release", st) && - !_print_ascii_file("/etc/angstrom-version", st) && - !_print_ascii_file("/etc/system-release", st) && - !_print_ascii_file("/etc/os-release", st)) { - - if (file_exists("/etc/debian_version")) { - st->print("Debian "); - _print_ascii_file("/etc/debian_version", st); - } else { - st->print("Linux"); + for (int i = 0;; i++) { + const char* file = distro_files[i]; + if (file == NULL) { + break; // done + } + // If file prints, we found it. + if (_print_ascii_file(file, st)) { + return; } } + + if (file_exists("/etc/debian_version")) { + st->print("Debian "); + _print_ascii_file("/etc/debian_version", st); + } else { + st->print("Linux"); + } st->cr(); } +static void parse_os_info(char* distro, size_t length, const char* file) { + FILE* fp = fopen(file, "r"); + if (fp != NULL) { + char buf[256]; + // get last line of the file. + while (!feof(fp)) { + fgets(buf, sizeof(buf), fp); + } + // Edit out ubuntu things + if (strstr(buf, "DISTRIB_DESCRIPTION=") != NULL) { + char* ptr = strstr(buf, "\""); + if (ptr != NULL) { + ptr++; // go beyond first " + char* nl = strchr(ptr, '\"'); + if (nl != NULL) *nl = '\0'; + strncpy(distro, ptr, length); + fclose(fp); + return; + } + } else { + // if not Ubuntu, print out whole line minus \n + char* nl = strchr(buf, '\n'); + if (nl != NULL) *nl = '\0'; + strncpy(distro, buf, length); + fclose(fp); + return; + } + } +} + +void os::get_summary_os_info(char* buf, size_t buflen) { + for (int i = 0;; i++) { + const char* file = distro_files[i]; + if (file == NULL) { + break; // ran out of distro_files + } + if (file_exists(file)) { + parse_os_info(buf, buflen, file); + return; + } + } + // special case for debian + if (file_exists("/etc/debian_version")) { + strncpy(buf, "Debian ", buflen); + parse_os_info(&buf[7], buflen-7, "/etc/debian_version"); + } else { + strncpy(buf, "Linux", buflen); + } +} + void os::Linux::print_libversion_info(outputStream* st) { // libc, pthread st->print("libc:"); @@ -2150,6 +2213,47 @@ } } +const char* search_string = IA32_ONLY("model name") AMD64_ONLY("model name") + IA64_ONLY("") SPARC_ONLY("cpu") + ARM32_ONLY("Processor") PPC_ONLY("Processor") AARCH64_ONLY("Processor"); + +// Parses the cpuinfo file for string representing the model name. +void os::get_summary_cpu_info(char* cpuinfo, size_t length) { + FILE* fp = fopen("/proc/cpuinfo", "r"); + if (fp != NULL) { + while (!feof(fp)) { + char buf[256]; + if (fgets(buf, sizeof(buf), fp)) { + char* start = strstr(buf, search_string); + if (start != NULL) { + char *ptr = start + strlen(search_string); + char *end = buf + strlen(buf); + while (ptr != end) { + // skip whitespace and colon for the rest of the name. + if (*ptr != ' ' && *ptr != '\t' && *ptr != ':') { + break; + } + ptr++; + } + if (ptr != end) { + // reasonable string, get rid of newline and keep the rest + char* nl = strchr(buf, '\n'); + if (nl != NULL) *nl = '\0'; + strncpy(cpuinfo, ptr, length); + fclose(fp); + return; + } + } + } + } + } + // cpuinfo not found or parsing failed, just print generic string. The entire + // /proc/cpuinfo file will be printed later in the file (or enough of it for x86) + strncpy(cpuinfo, IA32_ONLY("x86 IA32") AMD64_ONLY("x86 IA64") + IA64_ONLY("IA64") SPARC_ONLY("sparcv9") + ARM32_ONLY("ARM32") PPC_ONLY("PPC64") AARCH64_ONLY("AArch64"), length); +} + void os::print_siginfo(outputStream* st, void* siginfo) { const siginfo_t* si = (const siginfo_t*)siginfo; --- old/src/os/posix/vm/os_posix.cpp 2015-07-17 15:15:09.942489827 -0400 +++ new/src/os/posix/vm/os_posix.cpp 2015-07-17 15:15:08.602338658 -0400 @@ -236,6 +236,15 @@ st->cr(); } +#ifndef PRODUCT +bool os::get_host_name(char* buf, size_t buflen) { + struct utsname name; + uname(&name); + jio_snprintf(buf, buflen, "%s", name.nodename); + return true; +} +#endif // PRODUCT + bool os::has_allocatable_memory_limit(julong* limit) { struct rlimit rlim; int getrlimit_res = getrlimit(RLIMIT_AS, &rlim); --- old/src/share/vm/utilities/vmError.cpp 2015-07-17 15:15:09.124969186 -0400 +++ new/src/share/vm/utilities/vmError.cpp 2015-07-17 15:15:08.127410327 -0400 @@ -306,6 +306,30 @@ #endif // ZERO } +void VMError::print_oom_reasons(outputStream* st) { + st->print_cr("# Possible reasons:"); + st->print_cr("# The system is out of physical RAM or swap space"); + st->print_cr("# In 32 bit mode, the process size limit was hit"); + st->print_cr("# Possible solutions:"); + st->print_cr("# Reduce memory load on the system"); + st->print_cr("# Increase physical memory or swap space"); + st->print_cr("# Check if swap backing store is full"); + st->print_cr("# Use 64 bit Java on a 64 bit OS"); + st->print_cr("# Decrease Java heap size (-Xmx/-Xms)"); + st->print_cr("# Decrease number of Java threads"); + st->print_cr("# Decrease Java thread stack sizes (-Xss)"); + st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize="); + st->print_cr("# This output file may be truncated or incomplete."); +} + +const char* VMError::gc_mode() { + if (UseG1GC) return "g1 gc"; + if (UseParallelGC) return "parallel gc"; + if (UseConcMarkSweepGC) return "concurrent mark sweep gc"; + if (UseSerialGC) return "serial gc"; + return "ERROR in GC mode"; +} + // This is the main function to report a fatal error. Only one thread can // call this function, so we don't need to worry about MT-safety. But it's // possible that the error handler itself may crash or die on an internal @@ -358,21 +382,21 @@ // test secondary error handling. Test it twice, to test that resetting // error handler after a secondary crash works. - STEP(11, "(test secondary crash 1)") + STEP(20, "(test secondary crash 1)") if (_verbose && TestCrashInErrorHandler != 0) { st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...", TestCrashInErrorHandler); controlled_crash(TestCrashInErrorHandler); } - STEP(12, "(test secondary crash 2)") + STEP(30, "(test secondary crash 2)") if (_verbose && TestCrashInErrorHandler != 0) { st->print_cr("Will crash now (TestCrashInErrorHandler=%d)...", TestCrashInErrorHandler); controlled_crash(TestCrashInErrorHandler); } - STEP(13, "(test safefetch in error handler)") + STEP(40, "(test safefetch in error handler)") // test whether it is safe to use SafeFetch32 in Crash Handler. Test twice // to test that resetting the signal handler works correctly. if (_verbose && TestSafeFetchInErrorHandler) { @@ -393,7 +417,7 @@ } #endif // PRODUCT - STEP(15, "(printing type of error)") + STEP(50, "(printing type of error)") switch(_id) { case OOM_MALLOC_ERROR: @@ -418,19 +442,7 @@ } // In error file give some solutions if (_verbose) { - st->print_cr("# Possible reasons:"); - st->print_cr("# The system is out of physical RAM or swap space"); - st->print_cr("# In 32 bit mode, the process size limit was hit"); - st->print_cr("# Possible solutions:"); - st->print_cr("# Reduce memory load on the system"); - st->print_cr("# Increase physical memory or swap space"); - st->print_cr("# Check if swap backing store is full"); - st->print_cr("# Use 64 bit Java on a 64 bit OS"); - st->print_cr("# Decrease Java heap size (-Xmx/-Xms)"); - st->print_cr("# Decrease number of Java threads"); - st->print_cr("# Decrease Java thread stack sizes (-Xss)"); - st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize="); - st->print_cr("# This output file may be truncated or incomplete."); + print_oom_reasons(st); } else { return; // that's enough for the screen } @@ -440,7 +452,7 @@ break; } - STEP(20, "(printing exception/signal name)") + STEP(60, "(printing exception/signal name)") st->print_cr("#"); st->print("# "); @@ -470,14 +482,14 @@ } } - STEP(30, "(printing current thread and pid)") + STEP(70, "(printing current thread and pid)") // process id, thread id st->print(", pid=%d", os::current_process_id()); st->print(", tid=" INTPTR_FORMAT, os::current_thread_id()); st->cr(); - STEP(40, "(printing error message)") + STEP(80, "(printing error message)") if (should_report_bug(_id)) { // already printed the message. // error message @@ -488,7 +500,7 @@ } } - STEP(50, "(printing Java version string)") + STEP(90, "(printing Java version string)") // VM version st->print_cr("#"); @@ -498,15 +510,18 @@ const char* runtime_version = JDK_Version::runtime_version() != NULL ? JDK_Version::runtime_version() : ""; st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version); - st->print_cr("# Java VM: %s (%s %s %s %s)", + // This is the long version with some default settings added + st->print_cr("# Java VM: %s (%s, %s%s%s, %s, %s)", Abstract_VM_Version::vm_name(), Abstract_VM_Version::vm_release(), Abstract_VM_Version::vm_info_string(), - Abstract_VM_Version::vm_platform_string(), - UseCompressedOops ? "compressed oops" : "" + TieredCompilation ? ", tiered" : "", + UseCompressedOops ? ", compressed oops" : "", + gc_mode(), + Abstract_VM_Version::vm_platform_string() ); - STEP(60, "(printing problematic frame)") + STEP(100, "(printing problematic frame)") // Print current frame if we have a context (i.e. it's a crash) if (_context) { @@ -517,7 +532,8 @@ st->cr(); st->print_cr("#"); } - STEP(63, "(printing core file information)") + + STEP(110, "(printing core file information)") st->print("# "); if (CreateCoredumpOnCrash) { if (coredump_status) { @@ -531,13 +547,42 @@ st->cr(); st->print_cr("#"); - STEP(65, "(printing bug submit message)") + STEP(120, "(printing bug submit message)") if (should_report_bug(_id) && _verbose) { print_bug_submit_message(st, _thread); } - STEP(70, "(printing thread)" ) + STEP(130, "(printing summary)" ) + + if (_verbose) { + st->cr(); + st->print_cr("--------------- S U M M A R Y ------------"); + st->cr(); + } + + STEP(140, "(printing VM option summary)" ) + + if (_verbose) { + // VM options + Arguments::print_summary_on(st); + st->cr(); + } + + STEP(150, "(printing summary machine and OS info)") + + if (_verbose) { + os::print_summary_info(st, buf, sizeof(buf)); + } + + + STEP(160, "(printing date and time)" ) + + if (_verbose) { + os::print_date_and_time(st, buf, sizeof(buf)); + } + + STEP(170, "(printing thread)" ) if (_verbose) { st->cr(); @@ -545,7 +590,7 @@ st->cr(); } - STEP(80, "(printing current thread)" ) + STEP(180, "(printing current thread)" ) // current thread if (_verbose) { @@ -559,31 +604,20 @@ st->cr(); } - STEP(90, "(printing siginfo)" ) + STEP(190, "(printing current compile task)" ) - // signal no, signal code, address that caused the fault - if (_verbose && _siginfo) { - os::print_siginfo(st, _siginfo); - st->cr(); + if (_verbose && _thread && _thread->is_Compiler_thread()) { + CompilerThread* t = (CompilerThread*)_thread; + if (t->task()) { + st->cr(); + st->print_cr("Current CompileTask:"); + t->task()->print_line_on_error(st, buf, sizeof(buf)); + st->cr(); + } } - STEP(100, "(printing registers, top of stack, instructions near pc)") - // registers, top of stack, instructions near pc - if (_verbose && _context) { - os::print_context(st, _context); - st->cr(); - } - - STEP(105, "(printing register info)") - - // decode register contents if possible - if (_verbose && _context && Universe::is_fully_initialized()) { - os::print_register_info(st, _context); - st->cr(); - } - - STEP(110, "(printing stack bounds)" ) + STEP(200, "(printing stack bounds)" ) if (_verbose) { st->print("Stack: "); @@ -614,7 +648,7 @@ st->cr(); } - STEP(120, "(printing native stack)" ) + STEP(210, "(printing native stack)" ) if (_verbose) { if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) { @@ -628,13 +662,13 @@ } } - STEP(130, "(printing Java stack)" ) + STEP(220, "(printing Java stack)" ) if (_verbose && _thread && _thread->is_Java_thread()) { print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf)); } - STEP(135, "(printing target Java thread stack)" ) + STEP(230, "(printing target Java thread stack)" ) // printing Java thread stack trace if it is involved in GC crash if (_verbose && _thread && (_thread->is_Named_thread())) { @@ -645,7 +679,32 @@ } } - STEP(140, "(printing VM operation)" ) + STEP(240, "(printing siginfo)" ) + + // signal no, signal code, address that caused the fault + if (_verbose && _siginfo) { + st->cr(); + os::print_siginfo(st, _siginfo); + st->cr(); + } + + STEP(250, "(printing register info)") + + // decode register contents if possible + if (_verbose && _context && Universe::is_fully_initialized()) { + os::print_register_info(st, _context); + st->cr(); + } + + STEP(260, "(printing registers, top of stack, instructions near pc)") + + // registers, top of stack, instructions near pc + if (_verbose && _context) { + os::print_context(st, _context); + st->cr(); + } + + STEP(270, "(printing VM operation)" ) if (_verbose && _thread && _thread->is_VM_thread()) { VMThread* t = (VMThread*)_thread; @@ -657,19 +716,7 @@ } } - STEP(150, "(printing current compile task)" ) - - if (_verbose && _thread && _thread->is_Compiler_thread()) { - CompilerThread* t = (CompilerThread*)_thread; - if (t->task()) { - st->cr(); - st->print_cr("Current CompileTask:"); - t->task()->print_line_on_error(st, buf, sizeof(buf)); - st->cr(); - } - } - - STEP(160, "(printing process)" ) + STEP(280, "(printing process)" ) if (_verbose) { st->cr(); @@ -677,7 +724,7 @@ st->cr(); } - STEP(170, "(printing all threads)" ) + STEP(290, "(printing all threads)" ) // all threads if (_verbose && _thread) { @@ -685,7 +732,7 @@ st->cr(); } - STEP(175, "(printing VM state)" ) + STEP(300, "(printing VM state)" ) if (_verbose) { // Safepoint state @@ -707,7 +754,7 @@ st->cr(); } - STEP(180, "(printing owned locks on error)" ) + STEP(310, "(printing owned locks on error)" ) // mutexes/monitors that currently have an owner if (_verbose) { @@ -715,7 +762,7 @@ st->cr(); } - STEP(182, "(printing number of OutOfMemoryError and StackOverflow exceptions)") + STEP(320, "(printing number of OutOfMemoryError and StackOverflow exceptions)") if (_verbose && Exceptions::has_exception_counts()) { st->print_cr("OutOfMemory and StackOverflow Exception counts:"); @@ -723,7 +770,7 @@ st->cr(); } - STEP(185, "(printing compressed oops mode") + STEP(330, "(printing compressed oops mode") if (_verbose && UseCompressedOops) { Universe::print_compressed_oops_mode(st); @@ -733,7 +780,7 @@ st->cr(); } - STEP(190, "(printing heap information)" ) + STEP(340, "(printing heap information)" ) if (_verbose && Universe::is_fully_initialized()) { Universe::heap()->print_on_error(st); @@ -743,7 +790,7 @@ st->cr(); } - STEP(195, "(printing code cache information)" ) + STEP(350, "(printing code cache information)" ) if (_verbose && Universe::is_fully_initialized()) { // print code cache information before vm abort @@ -751,14 +798,14 @@ st->cr(); } - STEP(200, "(printing ring buffers)" ) + STEP(360, "(printing ring buffers)" ) if (_verbose) { Events::print_all(st); st->cr(); } - STEP(205, "(printing dynamic libraries)" ) + STEP(370, "(printing dynamic libraries)" ) if (_verbose) { // dynamic libraries, or memory map @@ -766,41 +813,42 @@ st->cr(); } - STEP(210, "(printing VM options)" ) + STEP(380, "(printing VM options)" ) if (_verbose) { // VM options Arguments::print_on(st); st->cr(); } + - STEP(215, "(printing warning if internal testing API used)" ) + STEP(390, "(printing warning if internal testing API used)" ) if (WhiteBox::used()) { st->print_cr("Unsupported internal testing APIs have been used."); st->cr(); } - STEP(220, "(printing environment variables)" ) + STEP(400, "(printing all environment variables)" ) if (_verbose) { os::print_environment_variables(st, env_list); st->cr(); } - STEP(225, "(printing signal handlers)" ) + STEP(410, "(printing signal handlers)" ) if (_verbose) { os::print_signal_handlers(st, buf, sizeof(buf)); st->cr(); } - STEP(228, "(Native Memory Tracking)" ) + STEP(420, "(Native Memory Tracking)" ) if (_verbose) { MemTracker::error_report(st); } - STEP(230, "" ) + STEP(430, "(printing system)" ) if (_verbose) { st->cr(); @@ -808,48 +856,39 @@ st->cr(); } - STEP(240, "(printing OS information)" ) + STEP(440, "(printing OS information)" ) if (_verbose) { os::print_os_info(st); st->cr(); } - STEP(250, "(printing CPU info)" ) + STEP(450, "(printing CPU info)" ) if (_verbose) { os::print_cpu_info(st, buf, sizeof(buf)); st->cr(); } - STEP(260, "(printing memory info)" ) + STEP(460, "(printing memory info)" ) if (_verbose) { os::print_memory_info(st); st->cr(); } - STEP(270, "(printing internal vm info)" ) + STEP(470, "(printing internal vm info)" ) if (_verbose) { st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string()); st->cr(); } - STEP(280, "(printing date and time)" ) - - if (_verbose) { - os::print_date_and_time(st, buf, sizeof(buf)); - st->cr(); - } - -#ifndef PRODUCT // print a defined marker to show that error handling finished correctly. - STEP(290, "(printing end marker)" ) + STEP(480, "(printing end marker)" ) if (_verbose) { st->print_cr("END."); } -#endif END --- old/src/os/aix/vm/os_aix.cpp 2015-07-17 15:15:09.100874255 -0400 +++ new/src/os/aix/vm/os_aix.cpp 2015-07-17 15:15:08.100517270 -0400 @@ -1550,6 +1550,13 @@ LoadedLibraries::print(st); } +void os::get_summary_os_info(char* buf, size_t buflen) { + // There might be something more readable than uname results for AIX. + struct utsname name; + uname(&name); + snprintf(buf, buflen, "%s %s", name.release, name.version); +} + void os::print_os_info(outputStream* st) { st->print("OS:"); @@ -1654,6 +1661,17 @@ } } +// Get a string for the cpuinfo that is a summary of the cpu type +void os::get_summary_cpu_info(char* buf, size_t buflen) { + // This looks good + os::Aix::cpuinfo_t ci; + if (os::Aix::get_cpuinfo(&ci)) { + strncpy(buf, ci.version, buflen); + } else { + strncpy(buf, "AIX", buflen); + } +} + void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { } --- old/src/share/vm/runtime/os.cpp 2015-07-17 15:15:08.885672830 -0400 +++ new/src/share/vm/runtime/os.cpp 2015-07-17 15:15:07.950211713 -0400 @@ -843,6 +843,22 @@ pd_print_cpu_info(st, buf, buflen); } +// Print a one line string summarizing the cpu, number of cores, memory, and operating system version +void os::print_summary_info(outputStream* st, char* buf, size_t buflen) { + st->print("Host: "); +#ifndef PRODUCT + if (get_host_name(buf, buflen)) { + st->print("%s, ", buf); + } +#endif // PRODUCT + get_summary_cpu_info(buf, buflen); + st->print("%s, ", buf); + st->print("%d cores, %dG, ", processor_count(), physical_memory()/G); + get_summary_os_info(buf, buflen); + st->print_raw(buf); + st->cr(); +} + void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) { const int secs_per_day = 86400; const int secs_per_hour = 3600; @@ -850,12 +866,19 @@ time_t tloc; (void)time(&tloc); - st->print("time: %s", ctime(&tloc)); // ctime adds newline. + char* timestring = ctime(&tloc); // ctime adds newline. + // edit out the newline + char* nl = strchr(timestring, '\n'); + if (nl != NULL) { + *nl = '\0'; + } struct tm tz; if (localtime_pd(&tloc, &tz) != NULL) { ::strftime(buf, buflen, "%Z", &tz); - st->print_cr("timezone: %s", buf); + st->print("Time: %s %s", timestring, buf); + } else { + st->print("Time: %s", timestring); } double t = os::elapsedTime(); @@ -872,7 +895,7 @@ int elmins = (eltime - day_secs - hour_secs) / secs_per_min; int minute_secs = elmins * secs_per_min; int elsecs = (eltime - day_secs - hour_secs - minute_secs); - st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); + st->print_cr(" elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); } // moved from debug.cpp (used to be find()) but still called from there --- old/src/os/windows/vm/os_windows.cpp 2015-07-17 15:15:10.159988662 -0400 +++ new/src/os/windows/vm/os_windows.cpp 2015-07-17 15:15:08.520553814 -0400 @@ -1593,6 +1593,21 @@ return result; } +#ifndef PRODUCT +bool os::get_host_name(char* buf, size_t buflen) { + DWORD size = (DWORD)buflen; + return (GetComputerNameEx(ComputerNameDnsHostname, buf, &size) == TRUE); +} +#endif // PRODUCT + +void os::get_summary_os_info(char* buf, size_t buflen) { + stringStream sst(buf, buflen); + os::win32::print_windows_version(&sst); + // chop off newline character + char* nl = strchr(buf, '\n'); + if (nl != NULL) *nl = '\0'; +} + void os::print_os_info_brief(outputStream* st) { os::print_os_info(st); } @@ -1600,15 +1615,14 @@ void os::print_os_info(outputStream* st) { #ifdef ASSERT char buffer[1024]; - DWORD size = sizeof(buffer); - st->print(" HostName: "); - if (GetComputerNameEx(ComputerNameDnsHostname, buffer, &size)) { - st->print("%s", buffer); + st->print("HostName: "); + if (get_host_name(buffer, sizeof(buffer))) { + st->print("%s ", buffer); } else { - st->print("N/A"); + st->print("N/A "); } #endif - st->print(" OS:"); + st->print("OS:"); os::win32::print_windows_version(st); } @@ -1738,6 +1752,23 @@ // Nothing to do for now. } +void os::get_summary_cpu_info(char* buf, size_t buflen) { + HKEY key; + DWORD status = RegOpenKey(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key); + if (status == ERROR_SUCCESS) { + DWORD size = (DWORD)buflen; + status = RegQueryValueEx(key, "ProcessorNameString", NULL, NULL, (byte*)buf, &size); + if (status != ERROR_SUCCESS) { + strncpy(buf, "## __CPU__", buflen); + } + RegCloseKey(key); + } else { + // Put generic cpu info to return + strncpy(buf, "## __CPU__", buflen); + } +} + void os::print_memory_info(outputStream* st) { st->print("Memory:"); st->print(" %dk page", os::vm_page_size()>>10); --- old/src/share/vm/runtime/arguments.cpp 2015-07-17 15:15:09.738405451 -0400 +++ new/src/share/vm/runtime/arguments.cpp 2015-07-17 15:15:07.881083723 -0400 @@ -788,9 +788,11 @@ st->print_cr("VM Arguments:"); if (num_jvm_flags() > 0) { st->print("jvm_flags: "); print_jvm_flags_on(st); + st->cr(); } if (num_jvm_args() > 0) { st->print("jvm_args: "); print_jvm_args_on(st); + st->cr(); } st->print_cr("java_command: %s", java_command() ? java_command() : ""); if (_java_class_path != NULL) { @@ -800,12 +802,32 @@ st->print_cr("Launcher Type: %s", _sun_java_launcher); } +void Arguments::print_summary_on(outputStream* st) { + // Print the command line. Environment variables that are helpful for + // reproducing the problem are written later in the hs_err file. + // flags are from setting file + if (num_jvm_flags() > 0) { + st->print_raw("Settings File: "); + print_jvm_flags_on(st); + st->cr(); + } + // args are the command line and environment variable arguments. + st->print_raw("Command Line: "); + if (num_jvm_args() > 0) { + print_jvm_args_on(st); + } + // this is the classfile and any arguments to the java program + if (java_command() != NULL) { + st->print("%s", java_command()); + } + st->cr(); +} + void Arguments::print_jvm_flags_on(outputStream* st) { if (_num_jvm_flags > 0) { for (int i=0; i < _num_jvm_flags; i++) { st->print("%s ", _jvm_flags_array[i]); } - st->cr(); } } @@ -814,7 +836,6 @@ for (int i=0; i < _num_jvm_args; i++) { st->print("%s ", _jvm_args_array[i]); } - st->cr(); } } --- old/src/os/solaris/vm/os_solaris.cpp 2015-07-17 15:15:09.360589032 -0400 +++ new/src/os/solaris/vm/os_solaris.cpp 2015-07-17 15:15:08.308516084 -0400 @@ -1971,6 +1971,26 @@ st->cr(); } +void os::get_summary_os_info(char* buf, size_t buflen) { + strncpy(buf, "Solaris", buflen); // default to plain solaris + FILE* fp = fopen("/etc/release", "r"); + if (fp != NULL) { + char tmp[256]; + // Only get the first line and chop out everything but the os name. + if (fgets(tmp, sizeof(tmp), fp)) { + char* ptr = tmp; + // skip past whitespace characters + while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')) ptr++; + if (*ptr != '\0') { + char* nl = strchr(ptr, '\n'); + if (nl != NULL) *nl = '\0'; + strncpy(buf, ptr, buflen); + } + } + fclose(fp); + } +} + void os::Solaris::print_libversion_info(outputStream* st) { st->print(" (T2 libthread)"); st->cr(); @@ -1998,6 +2018,22 @@ return status; } +void os::get_summary_cpu_info(char* buf, size_t buflen) { + // Get MHz with system call. We don't seem to already have this. + processor_info_t stats; + processorid_t id = getcpuid(); + int clock = 0; + if (processor_info(id, &stats) != -1) { + clock = stats.pi_clock; // pi_processor_type isn't more informative than below + } +#ifdef AMD64 + snprintf(buf, buflen, "x86 64 bit %d MHz", clock); +#else + // must be sparc + snprintf(buf, buflen, "Sparcv9 64 bit %d MHz", clock); +#endif +} + void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { // Nothing to do for now. } --- old/src/share/vm/runtime/arguments.hpp 2015-07-17 15:15:08.921879565 -0400 +++ new/src/share/vm/runtime/arguments.hpp 2015-07-17 15:15:07.462518527 -0400 @@ -491,6 +491,7 @@ // print jvm_flags, jvm_args and java_command static void print_on(outputStream* st); + static void print_summary_on(outputStream* st); // convenient methods to obtain / print jvm_flags and jvm_args static const char* jvm_flags() { return build_resource_string(_jvm_flags_array, _num_jvm_flags); } --- old/src/share/vm/runtime/os.hpp 2015-07-17 15:15:09.581415606 -0400 +++ new/src/share/vm/runtime/os.hpp 2015-07-17 15:15:08.566307497 -0400 @@ -150,6 +150,11 @@ static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned); + // Get summary strings for system information in buffer provided + static bool get_host_name(char* buf, size_t buflen) PRODUCT_RETURN_(false); // true if available + static void get_summary_cpu_info(char* buf, size_t buflen); + static void get_summary_os_info(char* buf, size_t buflen); + public: static void init(void); // Called before command line parsing static void init_before_ergo(void); // Called after command line parsing @@ -590,6 +595,7 @@ static void print_os_info_brief(outputStream* st); static void print_cpu_info(outputStream* st, char* buf, size_t buflen); static void pd_print_cpu_info(outputStream* st, char* buf, size_t buflen); + static void print_summary_info(outputStream* st, char* buf, size_t buflen); static void print_memory_info(outputStream* st); static void print_dll_info(outputStream* st); static void print_environment_variables(outputStream* st, const char** env_list);