Mon, 28 Feb 2011 15:35:45 -0800
Merge
1.1 --- a/src/os/linux/vm/os_linux.cpp Fri Feb 25 12:46:49 2011 -0800 1.2 +++ b/src/os/linux/vm/os_linux.cpp Mon Feb 28 15:35:45 2011 -0800 1.3 @@ -2213,7 +2213,7 @@ 1.4 if (rp == NULL) 1.5 return; 1.6 1.7 - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { 1.8 + if (Arguments::created_by_gamma_launcher()) { 1.9 // Support for the gamma launcher. Typical value for buf is 1.10 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at 1.11 // the right place in the string, then assume we are installed in a JDK and
2.1 --- a/src/os/posix/vm/os_posix.cpp Fri Feb 25 12:46:49 2011 -0800 2.2 +++ b/src/os/posix/vm/os_posix.cpp Mon Feb 28 15:35:45 2011 -0800 2.3 @@ -59,3 +59,12 @@ 2.4 VMError::report_coredump_status(buffer, success); 2.5 } 2.6 2.7 +bool os::is_debugger_attached() { 2.8 + // not implemented 2.9 + return false; 2.10 +} 2.11 + 2.12 +void os::wait_for_keypress_at_exit(void) { 2.13 + // don't do anything on posix platforms 2.14 + return; 2.15 +}
3.1 --- a/src/os/solaris/vm/os_solaris.cpp Fri Feb 25 12:46:49 2011 -0800 3.2 +++ b/src/os/solaris/vm/os_solaris.cpp Mon Feb 28 15:35:45 2011 -0800 3.3 @@ -2511,7 +2511,7 @@ 3.4 assert(ret != 0, "cannot locate libjvm"); 3.5 realpath((char *)dlinfo.dli_fname, buf); 3.6 3.7 - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { 3.8 + if (Arguments::created_by_gamma_launcher()) { 3.9 // Support for the gamma launcher. Typical value for buf is 3.10 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at 3.11 // the right place in the string, then assume we are installed in a JDK and
4.1 --- a/src/os/windows/vm/os_windows.cpp Fri Feb 25 12:46:49 2011 -0800 4.2 +++ b/src/os/windows/vm/os_windows.cpp Mon Feb 28 15:35:45 2011 -0800 4.3 @@ -1788,7 +1788,7 @@ 4.4 } 4.5 4.6 buf[0] = '\0'; 4.7 - if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { 4.8 + if (Arguments::created_by_gamma_launcher()) { 4.9 // Support for the gamma launcher. Check for an 4.10 // JAVA_HOME environment variable 4.11 // and fix up the path so it looks like 4.12 @@ -3418,6 +3418,19 @@ 4.13 } 4.14 4.15 4.16 +bool os::is_debugger_attached() { 4.17 + return IsDebuggerPresent() ? true : false; 4.18 +} 4.19 + 4.20 + 4.21 +void os::wait_for_keypress_at_exit(void) { 4.22 + if (PauseAtExit) { 4.23 + fprintf(stderr, "Press any key to continue...\n"); 4.24 + fgetc(stdin); 4.25 + } 4.26 +} 4.27 + 4.28 + 4.29 int os::message_box(const char* title, const char* message) { 4.30 int result = MessageBox(NULL, message, title, 4.31 MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);
5.1 --- a/src/share/vm/prims/jvmtiExport.cpp Fri Feb 25 12:46:49 2011 -0800 5.2 +++ b/src/share/vm/prims/jvmtiExport.cpp Mon Feb 28 15:35:45 2011 -0800 5.3 @@ -1805,6 +1805,10 @@ 5.4 5.5 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { 5.6 JavaThread* thread = JavaThread::current(); 5.7 + // In theory everyone coming thru here is in_vm but we need to be certain 5.8 + // because a callee will do a vm->native transition 5.9 + ThreadInVMfromUnknown __tiv; 5.10 + 5.11 EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, 5.12 ("JVMTI [%s] method dynamic code generated event triggered", 5.13 JvmtiTrace::safe_get_thread_name(thread))); 5.14 @@ -1826,19 +1830,18 @@ 5.15 } 5.16 5.17 void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) { 5.18 - // In theory everyone coming thru here is in_vm but we need to be certain 5.19 - // because a callee will do a vm->native transition 5.20 - ThreadInVMfromUnknown __tiv; 5.21 jvmtiPhase phase = JvmtiEnv::get_phase(); 5.22 if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) { 5.23 post_dynamic_code_generated_internal(name, code_begin, code_end); 5.24 - return; 5.25 + } else { 5.26 + // It may not be safe to post the event from this thread. Defer all 5.27 + // postings to the service thread so that it can perform them in a safe 5.28 + // context and in-order. 5.29 + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 5.30 + JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event( 5.31 + name, code_begin, code_end); 5.32 + JvmtiDeferredEventQueue::enqueue(event); 5.33 } 5.34 - 5.35 - // Blocks until everything now in the queue has been posted 5.36 - JvmtiDeferredEventQueue::flush_queue(Thread::current()); 5.37 - 5.38 - post_dynamic_code_generated_internal(name, code_begin, code_end); 5.39 } 5.40 5.41
6.1 --- a/src/share/vm/prims/jvmtiExport.hpp Fri Feb 25 12:46:49 2011 -0800 6.2 +++ b/src/share/vm/prims/jvmtiExport.hpp Mon Feb 28 15:35:45 2011 -0800 6.3 @@ -140,12 +140,12 @@ 6.4 char sig_type, jvalue *value); 6.5 6.6 6.7 - private: 6.8 // posts a DynamicCodeGenerated event (internal/private implementation). 6.9 // The public post_dynamic_code_generated* functions make use of the 6.10 - // internal implementation. 6.11 + // internal implementation. Also called from JvmtiDeferredEvent::post() 6.12 static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN; 6.13 6.14 + private: 6.15 6.16 // GenerateEvents support to allow posting of CompiledMethodLoad and 6.17 // DynamicCodeGenerated events for a given environment.
7.1 --- a/src/share/vm/prims/jvmtiImpl.cpp Fri Feb 25 12:46:49 2011 -0800 7.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp Mon Feb 28 15:35:45 2011 -0800 7.3 @@ -918,7 +918,7 @@ 7.4 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( 7.5 nmethod* nm) { 7.6 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); 7.7 - event.set_compiled_method_load(nm); 7.8 + event._event_data.compiled_method_load = nm; 7.9 nmethodLocker::lock_nmethod(nm); // will be unlocked when posted 7.10 return event; 7.11 } 7.12 @@ -926,23 +926,39 @@ 7.13 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( 7.14 jmethodID id, const void* code) { 7.15 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); 7.16 - event.set_compiled_method_unload(id, code); 7.17 + event._event_data.compiled_method_unload.method_id = id; 7.18 + event._event_data.compiled_method_unload.code_begin = code; 7.19 + return event; 7.20 +} 7.21 +JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event( 7.22 + const char* name, const void* code_begin, const void* code_end) { 7.23 + JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED); 7.24 + event._event_data.dynamic_code_generated.name = name; 7.25 + event._event_data.dynamic_code_generated.code_begin = code_begin; 7.26 + event._event_data.dynamic_code_generated.code_end = code_end; 7.27 return event; 7.28 } 7.29 7.30 void JvmtiDeferredEvent::post() { 7.31 + assert(ServiceThread::is_service_thread(Thread::current()), 7.32 + "Service thread must post enqueued events"); 7.33 switch(_type) { 7.34 - case TYPE_COMPILED_METHOD_LOAD: 7.35 - JvmtiExport::post_compiled_method_load(compiled_method_load()); 7.36 - nmethodLocker::unlock_nmethod(compiled_method_load()); 7.37 + case TYPE_COMPILED_METHOD_LOAD: { 7.38 + nmethod* nm = _event_data.compiled_method_load; 7.39 + JvmtiExport::post_compiled_method_load(nm); 7.40 + nmethodLocker::unlock_nmethod(nm); 7.41 break; 7.42 + } 7.43 case TYPE_COMPILED_METHOD_UNLOAD: 7.44 JvmtiExport::post_compiled_method_unload( 7.45 - compiled_method_unload_method_id(), 7.46 - compiled_method_unload_code_begin()); 7.47 + _event_data.compiled_method_unload.method_id, 7.48 + _event_data.compiled_method_unload.code_begin); 7.49 break; 7.50 - case TYPE_FLUSH: 7.51 - JvmtiDeferredEventQueue::flush_complete(flush_state_addr()); 7.52 + case TYPE_DYNAMIC_CODE_GENERATED: 7.53 + JvmtiExport::post_dynamic_code_generated_internal( 7.54 + _event_data.dynamic_code_generated.name, 7.55 + _event_data.dynamic_code_generated.code_begin, 7.56 + _event_data.dynamic_code_generated.code_end); 7.57 break; 7.58 default: 7.59 ShouldNotReachHere(); 7.60 @@ -1065,54 +1081,4 @@ 7.61 } 7.62 } 7.63 7.64 -enum { 7.65 - // Random - used for debugging 7.66 - FLUSHING = 0x50403020, 7.67 - FLUSHED = 0x09080706 7.68 -}; 7.69 - 7.70 -void JvmtiDeferredEventQueue::flush_queue(Thread* thread) { 7.71 - 7.72 - volatile int flush_state = FLUSHING; 7.73 - 7.74 - JvmtiDeferredEvent flush(JvmtiDeferredEvent::TYPE_FLUSH); 7.75 - flush.set_flush_state_addr((int*)&flush_state); 7.76 - 7.77 - if (ServiceThread::is_service_thread(thread)) { 7.78 - // If we are the service thread we have to post all preceding events 7.79 - // Use the flush event as a token to indicate when we can stop 7.80 - JvmtiDeferredEvent event; 7.81 - { 7.82 - MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 7.83 - enqueue(flush); 7.84 - event = dequeue(); 7.85 - } 7.86 - while (!event.is_flush_event() || 7.87 - event.flush_state_addr() != &flush_state) { 7.88 - event.post(); 7.89 - { 7.90 - MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 7.91 - event = dequeue(); 7.92 - } 7.93 - } 7.94 - } else { 7.95 - // Wake up the service thread so it will process events. When it gets 7.96 - // to the flush event it will set 'flush_complete' and notify us. 7.97 - MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 7.98 - enqueue(flush); 7.99 - while (flush_state != FLUSHED) { 7.100 - assert(flush_state == FLUSHING || flush_state == FLUSHED, 7.101 - "only valid values for this"); 7.102 - Service_lock->wait(Mutex::_no_safepoint_check_flag); 7.103 - } 7.104 - } 7.105 -} 7.106 - 7.107 -void JvmtiDeferredEventQueue::flush_complete(int* state_addr) { 7.108 - assert(state_addr != NULL && *state_addr == FLUSHING, "must be"); 7.109 - MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 7.110 - *state_addr = FLUSHED; 7.111 - Service_lock->notify_all(); 7.112 -} 7.113 - 7.114 #endif // ndef KERNEL
8.1 --- a/src/share/vm/prims/jvmtiImpl.hpp Fri Feb 25 12:46:49 2011 -0800 8.2 +++ b/src/share/vm/prims/jvmtiImpl.hpp Mon Feb 28 15:35:45 2011 -0800 8.3 @@ -451,7 +451,7 @@ 8.4 TYPE_NONE, 8.5 TYPE_COMPILED_METHOD_LOAD, 8.6 TYPE_COMPILED_METHOD_UNLOAD, 8.7 - TYPE_FLUSH // pseudo-event used to implement flush_queue() 8.8 + TYPE_DYNAMIC_CODE_GENERATED 8.9 } Type; 8.10 8.11 Type _type; 8.12 @@ -461,49 +461,15 @@ 8.13 jmethodID method_id; 8.14 const void* code_begin; 8.15 } compiled_method_unload; 8.16 - int* flush_state_addr; 8.17 + struct { 8.18 + const char* name; 8.19 + const void* code_begin; 8.20 + const void* code_end; 8.21 + } dynamic_code_generated; 8.22 } _event_data; 8.23 8.24 JvmtiDeferredEvent(Type t) : _type(t) {} 8.25 8.26 - void set_compiled_method_load(nmethod* nm) { 8.27 - assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); 8.28 - _event_data.compiled_method_load = nm; 8.29 - } 8.30 - 8.31 - nmethod* compiled_method_load() const { 8.32 - assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); 8.33 - return _event_data.compiled_method_load; 8.34 - } 8.35 - 8.36 - void set_compiled_method_unload(jmethodID id, const void* code) { 8.37 - assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); 8.38 - _event_data.compiled_method_unload.method_id = id; 8.39 - _event_data.compiled_method_unload.code_begin = code; 8.40 - } 8.41 - 8.42 - jmethodID compiled_method_unload_method_id() const { 8.43 - assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); 8.44 - return _event_data.compiled_method_unload.method_id; 8.45 - } 8.46 - 8.47 - const void* compiled_method_unload_code_begin() const { 8.48 - assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); 8.49 - return _event_data.compiled_method_unload.code_begin; 8.50 - } 8.51 - 8.52 - bool is_flush_event() const { return _type == TYPE_FLUSH; } 8.53 - 8.54 - int* flush_state_addr() const { 8.55 - assert(is_flush_event(), "must be"); 8.56 - return _event_data.flush_state_addr; 8.57 - } 8.58 - 8.59 - void set_flush_state_addr(int* flag) { 8.60 - assert(is_flush_event(), "must be"); 8.61 - _event_data.flush_state_addr = flag; 8.62 - } 8.63 - 8.64 public: 8.65 8.66 JvmtiDeferredEvent() : _type(TYPE_NONE) {} 8.67 @@ -513,6 +479,9 @@ 8.68 KERNEL_RETURN_(JvmtiDeferredEvent()); 8.69 static JvmtiDeferredEvent compiled_method_unload_event( 8.70 jmethodID id, const void* code) KERNEL_RETURN_(JvmtiDeferredEvent()); 8.71 + static JvmtiDeferredEvent dynamic_code_generated_event( 8.72 + const char* name, const void* begin, const void* end) 8.73 + KERNEL_RETURN_(JvmtiDeferredEvent()); 8.74 8.75 // Actually posts the event. 8.76 void post() KERNEL_RETURN; 8.77 @@ -548,25 +517,12 @@ 8.78 // Transfers events from the _pending_list to the _queue. 8.79 static void process_pending_events() KERNEL_RETURN; 8.80 8.81 - static void flush_complete(int* flush_state) KERNEL_RETURN; 8.82 - 8.83 public: 8.84 // Must be holding Service_lock when calling these 8.85 static bool has_events() KERNEL_RETURN_(false); 8.86 static void enqueue(const JvmtiDeferredEvent& event) KERNEL_RETURN; 8.87 static JvmtiDeferredEvent dequeue() KERNEL_RETURN_(JvmtiDeferredEvent()); 8.88 8.89 - // This call blocks until all events enqueued prior to this call 8.90 - // have been posted. The Service_lock is acquired and waited upon. 8.91 - // 8.92 - // Implemented by creating a "flush" event and placing it in the queue. 8.93 - // When the flush event is "posted" it will call flush_complete(), which 8.94 - // will release the caller. 8.95 - // 8.96 - // Can be called by any thread (maybe even the service thread itself). 8.97 - // Not necessary for the caller to be a JavaThread. 8.98 - static void flush_queue(Thread* current) KERNEL_RETURN; 8.99 - 8.100 // Used to enqueue events without using a lock, for times (such as during 8.101 // safepoint) when we can't or don't want to lock the Service_lock. 8.102 //
9.1 --- a/src/share/vm/runtime/arguments.cpp Fri Feb 25 12:46:49 2011 -0800 9.2 +++ b/src/share/vm/runtime/arguments.cpp Mon Feb 28 15:35:45 2011 -0800 9.3 @@ -78,6 +78,7 @@ 9.4 const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG; 9.5 const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER; 9.6 int Arguments::_sun_java_launcher_pid = -1; 9.7 +bool Arguments::_created_by_gamma_launcher = false; 9.8 9.9 // These parameters are reset in method parse_vm_init_args(JavaVMInitArgs*) 9.10 bool Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; 9.11 @@ -1656,6 +1657,9 @@ 9.12 9.13 void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) { 9.14 _sun_java_launcher = strdup(launcher); 9.15 + if (strcmp("gamma", _sun_java_launcher) == 0) { 9.16 + _created_by_gamma_launcher = true; 9.17 + } 9.18 } 9.19 9.20 bool Arguments::created_by_java_launcher() { 9.21 @@ -1663,6 +1667,10 @@ 9.22 return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0; 9.23 } 9.24 9.25 +bool Arguments::created_by_gamma_launcher() { 9.26 + return _created_by_gamma_launcher; 9.27 +} 9.28 + 9.29 //=========================================================================================================== 9.30 // Parsing of main arguments 9.31 9.32 @@ -3155,6 +3163,16 @@ 9.33 } 9.34 } 9.35 9.36 + // set PauseAtExit if the gamma launcher was used and a debugger is attached 9.37 + // but only if not already set on the commandline 9.38 + if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) { 9.39 + bool set = false; 9.40 + CommandLineFlags::wasSetOnCmdline("PauseAtExit", &set); 9.41 + if (!set) { 9.42 + FLAG_SET_DEFAULT(PauseAtExit, true); 9.43 + } 9.44 + } 9.45 + 9.46 return JNI_OK; 9.47 } 9.48
10.1 --- a/src/share/vm/runtime/arguments.hpp Fri Feb 25 12:46:49 2011 -0800 10.2 +++ b/src/share/vm/runtime/arguments.hpp Mon Feb 28 15:35:45 2011 -0800 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -257,6 +257,9 @@ 10.11 // sun.java.launcher.pid, private property 10.12 static int _sun_java_launcher_pid; 10.13 10.14 + // was this VM created by the gamma launcher 10.15 + static bool _created_by_gamma_launcher; 10.16 + 10.17 // Option flags 10.18 static bool _has_profile; 10.19 static bool _has_alloc_profile; 10.20 @@ -444,6 +447,8 @@ 10.21 static const char* sun_java_launcher() { return _sun_java_launcher; } 10.22 // Was VM created by a Java launcher? 10.23 static bool created_by_java_launcher(); 10.24 + // Was VM created by the gamma Java launcher? 10.25 + static bool created_by_gamma_launcher(); 10.26 // -Dsun.java.launcher.pid 10.27 static int sun_java_launcher_pid() { return _sun_java_launcher_pid; } 10.28
11.1 --- a/src/share/vm/runtime/globals.hpp Fri Feb 25 12:46:49 2011 -0800 11.2 +++ b/src/share/vm/runtime/globals.hpp Mon Feb 28 15:35:45 2011 -0800 11.3 @@ -3733,6 +3733,9 @@ 11.4 "The file to create and for whose removal to await when pausing " \ 11.5 "at startup. (default: ./vm.paused.<pid>)") \ 11.6 \ 11.7 + diagnostic(bool, PauseAtExit, false, \ 11.8 + "Pause and wait for keypress on exit if a debugger is attached") \ 11.9 + \ 11.10 product(bool, ExtendedDTraceProbes, false, \ 11.11 "Enable performance-impacting dtrace probes") \ 11.12 \
12.1 --- a/src/share/vm/runtime/java.cpp Fri Feb 25 12:46:49 2011 -0800 12.2 +++ b/src/share/vm/runtime/java.cpp Mon Feb 28 15:35:45 2011 -0800 12.3 @@ -551,6 +551,7 @@ 12.4 12.5 void vm_direct_exit(int code) { 12.6 notify_vm_shutdown(); 12.7 + os::wait_for_keypress_at_exit(); 12.8 ::exit(code); 12.9 } 12.10 12.11 @@ -577,11 +578,13 @@ 12.12 void vm_shutdown() 12.13 { 12.14 vm_perform_shutdown_actions(); 12.15 + os::wait_for_keypress_at_exit(); 12.16 os::shutdown(); 12.17 } 12.18 12.19 void vm_abort(bool dump_core) { 12.20 vm_perform_shutdown_actions(); 12.21 + os::wait_for_keypress_at_exit(); 12.22 os::abort(dump_core); 12.23 ShouldNotReachHere(); 12.24 }
13.1 --- a/src/share/vm/runtime/os.hpp Fri Feb 25 12:46:49 2011 -0800 13.2 +++ b/src/share/vm/runtime/os.hpp Mon Feb 28 15:35:45 2011 -0800 13.3 @@ -492,6 +492,12 @@ 13.4 static void print_location(outputStream* st, intptr_t x, bool verbose = false); 13.5 static size_t lasterror(char *buf, size_t len); 13.6 13.7 + // Determines whether the calling process is being debugged by a user-mode debugger. 13.8 + static bool is_debugger_attached(); 13.9 + 13.10 + // wait for a key press if PauseAtExit is set 13.11 + static void wait_for_keypress_at_exit(void); 13.12 + 13.13 // The following two functions are used by fatal error handler to trace 13.14 // native (C) frames. They are not part of frame.hpp/frame.cpp because 13.15 // frame.hpp/cpp assume thread is JavaThread, and also because different
14.1 --- a/src/share/vm/runtime/thread.cpp Fri Feb 25 12:46:49 2011 -0800 14.2 +++ b/src/share/vm/runtime/thread.cpp Mon Feb 28 15:35:45 2011 -0800 14.3 @@ -3644,6 +3644,7 @@ 14.4 if (ShowMessageBoxOnError && is_error_reported()) { 14.5 os::infinite_sleep(); 14.6 } 14.7 + os::wait_for_keypress_at_exit(); 14.8 14.9 if (JDK_Version::is_jdk12x_version()) { 14.10 // We are the last thread running, so check if finalizers should be run.
15.1 --- a/src/share/vm/utilities/vmError.cpp Fri Feb 25 12:46:49 2011 -0800 15.2 +++ b/src/share/vm/utilities/vmError.cpp Mon Feb 28 15:35:45 2011 -0800 15.3 @@ -802,7 +802,7 @@ 15.4 first_error_tid = mytid; 15.5 set_error_reported(); 15.6 15.7 - if (ShowMessageBoxOnError) { 15.8 + if (ShowMessageBoxOnError || PauseAtExit) { 15.9 show_message_box(buffer, sizeof(buffer)); 15.10 15.11 // User has asked JVM to abort. Reset ShowMessageBoxOnError so the