diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp index 6bdcdd2165c8e2aa3d0ab341645556aabf12ae33..a3975d89892351baf5a8aa26805f06cd4d492e6a 100644 --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -2213,7 +2213,7 @@ void os::jvm_path(char *buf, jint buflen) { if (rp == NULL) return; - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { + if (Arguments::created_by_gamma_launcher()) { // Support for the gamma launcher. Typical value for buf is // "/jre/lib///libjvm.so". If "/jre/lib/" appears at // the right place in the string, then assume we are installed in a JDK and diff --git a/src/os/posix/vm/os_posix.cpp b/src/os/posix/vm/os_posix.cpp index 079fa7bc0b2406eb5233ebaee7644ad88ede1e43..4795d06fbebb212009f51466b38db084775fedcd 100644 --- a/src/os/posix/vm/os_posix.cpp +++ b/src/os/posix/vm/os_posix.cpp @@ -59,3 +59,12 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* VMError::report_coredump_status(buffer, success); } +bool os::is_debugger_attached() { + // not implemented + return false; +} + +void os::wait_for_keypress_at_exit(void) { + // don't do anything on posix platforms + return; +} diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp index fad8d4466b5dba3ad0be1ef9b3eb45cdf82646c0..8bbd492bd936da39e3c160f3624f06c8e4e9eed1 100644 --- a/src/os/solaris/vm/os_solaris.cpp +++ b/src/os/solaris/vm/os_solaris.cpp @@ -2507,7 +2507,7 @@ void os::jvm_path(char *buf, jint buflen) { assert(ret != 0, "cannot locate libjvm"); realpath((char *)dlinfo.dli_fname, buf); - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { + if (Arguments::created_by_gamma_launcher()) { // Support for the gamma launcher. Typical value for buf is // "/jre/lib///libjvm.so". If "/jre/lib/" appears at // the right place in the string, then assume we are installed in a JDK and diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index 1b1f04bd0521317a9628da94de07b905fb8850cb..0992ce7648d96f211375f3aca1c9e0ce229f6702 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -1788,7 +1788,7 @@ void os::jvm_path(char *buf, jint buflen) { } buf[0] = '\0'; - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { + if (Arguments::created_by_gamma_launcher()) { // Support for the gamma launcher. Check for an // JAVA_HOME environment variable // and fix up the path so it looks like @@ -3418,6 +3418,19 @@ void os::win32::setmode_streams() { } +bool os::is_debugger_attached() { + return IsDebuggerPresent() ? true : false; +} + + +void os::wait_for_keypress_at_exit(void) { + if (PauseAtExit) { + fprintf(stderr, "Press any key to continue...\n"); + fgetc(stdin); + } +} + + int os::message_box(const char* title, const char* message) { int result = MessageBox(NULL, message, title, MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY); diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp index c058be086c4be754d1d914b050d8215e52bc4fa3..912312a31fce2bac58a5967b47dc56bd61ae5dab 100644 --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -78,6 +78,7 @@ bool Arguments::_xdebug_mode = false; const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG; const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER; int Arguments::_sun_java_launcher_pid = -1; +bool Arguments::_created_by_gamma_launcher = false; // These parameters are reset in method parse_vm_init_args(JavaVMInitArgs*) bool Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; @@ -1656,6 +1657,9 @@ void Arguments::process_java_compiler_argument(char* arg) { void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) { _sun_java_launcher = strdup(launcher); + if (strcmp("gamma", _sun_java_launcher) == 0) { + _created_by_gamma_launcher = true; + } } bool Arguments::created_by_java_launcher() { @@ -1663,6 +1667,10 @@ bool Arguments::created_by_java_launcher() { return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0; } +bool Arguments::created_by_gamma_launcher() { + return _created_by_gamma_launcher; +} + //=========================================================================================================== // Parsing of main arguments @@ -3155,6 +3163,16 @@ jint Arguments::parse(const JavaVMInitArgs* args) { } } + // set PauseAtExit if the gamma launcher was used and a debugger is attached + // but only if not already set on the commandline + if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) { + bool set = false; + CommandLineFlags::wasSetOnCmdline("PauseAtExit", &set); + if (!set) { + FLAG_SET_DEFAULT(PauseAtExit, true); + } + } + return JNI_OK; } diff --git a/src/share/vm/runtime/arguments.hpp b/src/share/vm/runtime/arguments.hpp index ed6ef26dd2e9dd363d54b24df5af49fc3402478a..fec2bf0f665741b44b7ea40d6ce3e9747a5ed819 100644 --- a/src/share/vm/runtime/arguments.hpp +++ b/src/share/vm/runtime/arguments.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -257,6 +257,9 @@ class Arguments : AllStatic { // sun.java.launcher.pid, private property static int _sun_java_launcher_pid; + // was this VM created by the gamma launcher + static bool _created_by_gamma_launcher; + // Option flags static bool _has_profile; static bool _has_alloc_profile; @@ -444,6 +447,8 @@ class Arguments : AllStatic { static const char* sun_java_launcher() { return _sun_java_launcher; } // Was VM created by a Java launcher? static bool created_by_java_launcher(); + // Was VM created by the gamma Java launcher? + static bool created_by_gamma_launcher(); // -Dsun.java.launcher.pid static int sun_java_launcher_pid() { return _sun_java_launcher_pid; } diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index bcb518661b9080b617f5d47addadd79b3c5fa53d..7587cb001134f0af6a54fcdd50b9042e9c543b3c 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -3730,6 +3730,9 @@ class CommandLineFlags { "The file to create and for whose removal to await when pausing " \ "at startup. (default: ./vm.paused.)") \ \ + diagnostic(bool, PauseAtExit, false, \ + "Pause and wait for keypress on exit if a debugger is attached") \ + \ product(bool, ExtendedDTraceProbes, false, \ "Enable performance-impacting dtrace probes") \ \ diff --git a/src/share/vm/runtime/java.cpp b/src/share/vm/runtime/java.cpp index f833dd2e400b0ab67ad64ef3e7cb28618a33a8f9..1d1bd65bab99e33db20c28297d89c68f2e5d6693 100644 --- a/src/share/vm/runtime/java.cpp +++ b/src/share/vm/runtime/java.cpp @@ -551,6 +551,7 @@ void notify_vm_shutdown() { void vm_direct_exit(int code) { notify_vm_shutdown(); + os::wait_for_keypress_at_exit(); ::exit(code); } @@ -577,11 +578,13 @@ void vm_perform_shutdown_actions() { void vm_shutdown() { vm_perform_shutdown_actions(); + os::wait_for_keypress_at_exit(); os::shutdown(); } void vm_abort(bool dump_core) { vm_perform_shutdown_actions(); + os::wait_for_keypress_at_exit(); os::abort(dump_core); ShouldNotReachHere(); } diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index 90ca497df550d70d291cce40052221cbce3d2378..927d0534d7bf308fe96a0fb60cde231cc894d99e 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -492,6 +492,12 @@ class os: AllStatic { static void print_location(outputStream* st, intptr_t x, bool verbose = false); static size_t lasterror(char *buf, size_t len); + // Determines whether the calling process is being debugged by a user-mode debugger. + static bool is_debugger_attached(); + + // wait for a key press if PauseAtExit is set + static void wait_for_keypress_at_exit(void); + // The following two functions are used by fatal error handler to trace // native (C) frames. They are not part of frame.hpp/frame.cpp because // frame.hpp/cpp assume thread is JavaThread, and also because different diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index 014df57ea1c3b47f707e8dee78f84db5aaff2388..c198e86b0a8c49b0696b3734cde24429625f8438 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -3644,6 +3644,7 @@ bool Threads::destroy_vm() { if (ShowMessageBoxOnError && is_error_reported()) { os::infinite_sleep(); } + os::wait_for_keypress_at_exit(); if (JDK_Version::is_jdk12x_version()) { // We are the last thread running, so check if finalizers should be run. diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp index 9785d649d087e9b1793fa7ae2b7acdd6dcbd05e7..fa8b82094cb041ed09ed6cffe9b0f6332bad9f7d 100644 --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -802,7 +802,7 @@ void VMError::report_and_die() { first_error_tid = mytid; set_error_reported(); - if (ShowMessageBoxOnError) { + if (ShowMessageBoxOnError || PauseAtExit) { show_message_box(buffer, sizeof(buffer)); // User has asked JVM to abort. Reset ShowMessageBoxOnError so the