--- old/src/os/linux/vm/os_linux.cpp 2011-02-25 09:59:22.299753000 +0100 +++ new/src/os/linux/vm/os_linux.cpp 2011-02-25 09:59:21.901730300 +0100 @@ -2213,7 +2213,7 @@ 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 --- old/src/os/posix/vm/os_posix.cpp 2011-02-25 09:59:28.525298700 +0100 +++ new/src/os/posix/vm/os_posix.cpp 2011-02-25 09:59:28.112275100 +0100 @@ -59,3 +59,8 @@ VMError::report_coredump_status(buffer, success); } +bool os::is_debugger_present() { + // not implemented + return false; +} + --- old/src/os/solaris/vm/os_solaris.cpp 2011-02-25 09:59:33.894196300 +0100 +++ new/src/os/solaris/vm/os_solaris.cpp 2011-02-25 09:59:33.501173800 +0100 @@ -2507,7 +2507,7 @@ 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 --- old/src/os/windows/vm/os_windows.cpp 2011-02-25 09:59:40.539766000 +0100 +++ new/src/os/windows/vm/os_windows.cpp 2011-02-25 09:59:40.148743700 +0100 @@ -1788,7 +1788,7 @@ } 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,11 @@ } +bool os::is_debugger_attached() { + return IsDebuggerPresent() ? true : false; +} + + 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); --- old/src/share/vm/runtime/arguments.cpp 2011-02-25 09:59:47.028326800 +0100 +++ new/src/share/vm/runtime/arguments.cpp 2011-02-25 09:59:46.632304100 +0100 @@ -1663,6 +1663,11 @@ return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0; } +bool Arguments::created_by_gamma_launcher() { + assert(_sun_java_launcher != NULL, "property must have value"); + return strcmp("gamma", _sun_java_launcher) == 0; +} + //=========================================================================================================== // Parsing of main arguments --- old/src/share/vm/runtime/arguments.hpp 2011-02-25 09:59:53.058861300 +0100 +++ new/src/share/vm/runtime/arguments.hpp 2011-02-25 09:59:52.664838800 +0100 @@ -444,6 +444,8 @@ 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; } --- old/src/share/vm/runtime/globals.hpp 2011-02-25 09:59:58.759980500 +0100 +++ new/src/share/vm/runtime/globals.hpp 2011-02-25 09:59:58.324559000 +0100 @@ -3749,6 +3749,10 @@ "The file to create and for whose removal to await when pausing " \ "at startup. (default: ./vm.paused.)") \ \ + diagnostic(bool, PauseAtExit, true, \ + "Pause and wait for keypress on exit if a debugger is attached " \ + "and the gamma launcher is used." \ + \ product(bool, ExtendedDTraceProbes, false, \ "Enable performance-impacting dtrace probes") \ \ --- old/src/share/vm/runtime/java.cpp 2011-02-25 10:00:05.040335400 +0100 +++ new/src/share/vm/runtime/java.cpp 2011-02-25 10:00:04.625311600 +0100 @@ -543,10 +543,21 @@ ShouldNotReachHere(); } +void wait_for_key_press(void) { +#ifdef TARGET_OS_FAMILY_windows + // if running in a debugger on windows, we want to pause before the console is closed + if (Arguments::created_by_gamma_launcher() && PauseAtExit && os::is_debugger_attached()) { + fprintf(stderr, "Press any key to continue...\n"); + fgetc(stdin); + } +#endif +} + void notify_vm_shutdown() { // For now, just a dtrace probe. HS_DTRACE_PROBE(hotspot, vm__shutdown); HS_DTRACE_WORKAROUND_TAIL_CALL_BUG(); + wait_for_key_press(); } void vm_direct_exit(int code) { --- old/src/share/vm/runtime/os.hpp 2011-02-25 10:00:10.895859900 +0100 +++ new/src/share/vm/runtime/os.hpp 2011-02-25 10:00:10.534839300 +0100 @@ -492,6 +492,9 @@ 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(); + // 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 --- old/src/share/vm/utilities/vmError.cpp 2011-02-25 10:00:16.364362300 +0100 +++ new/src/share/vm/utilities/vmError.cpp 2011-02-25 10:00:15.979943800 +0100 @@ -802,7 +802,9 @@ first_error_tid = mytid; set_error_reported(); - if (ShowMessageBoxOnError) { + if (ShowMessageBoxOnError || + (Arguments::created_by_gamma_launcher() && PauseAtExit && os::is_debugger_attached())) + { show_message_box(buffer, sizeof(buffer)); // User has asked JVM to abort. Reset ShowMessageBoxOnError so the