8136978: Much nearly duplicated code for vmError support
authorsebastian
Wed, 25 Nov 2015 16:33:28 +0100
changeset 34305 e399e6b44631
parent 34234 e4a23d294f48
child 34306 f64a5e6127f2
8136978: Much nearly duplicated code for vmError support Summary: moved all non os specific code in vmError_[os].cpp to vmError_posix.cpp, moved os specific code to os_[os].cpp and refactored all other references accordingly Reviewed-by: stuefe, coleenp, dholmes
hotspot/src/os/aix/vm/os_aix.cpp
hotspot/src/os/aix/vm/vmError_aix.cpp
hotspot/src/os/bsd/vm/os_bsd.cpp
hotspot/src/os/bsd/vm/vmError_bsd.cpp
hotspot/src/os/linux/vm/os_linux.cpp
hotspot/src/os/linux/vm/vmError_linux.cpp
hotspot/src/os/posix/vm/os_posix.cpp
hotspot/src/os/posix/vm/os_posix.hpp
hotspot/src/os/posix/vm/vmError_posix.cpp
hotspot/src/os/solaris/vm/os_solaris.cpp
hotspot/src/os/solaris/vm/vmError_solaris.cpp
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/src/os/windows/vm/vmError_windows.cpp
hotspot/src/share/vm/runtime/os.hpp
hotspot/src/share/vm/utilities/vmError.cpp
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -3785,7 +3785,7 @@
 void os::print_statistics() {
 }
 
-int os::message_box(const char* title, const char* message) {
+bool os::message_box(const char* title, const char* message) {
   int i;
   fdStream err(defaultStream::error_fd());
   for (i = 0; i < 78; i++) err.print_raw("=");
@@ -4914,3 +4914,28 @@
   // No tests available for this platform
 }
 #endif
+
+bool os::start_debugging(char *buf, int buflen) {
+  int len = (int)strlen(buf);
+  char *p = &buf[len];
+
+  jio_snprintf(p, buflen -len,
+                 "\n\n"
+                 "Do you want to debug the problem?\n\n"
+                 "To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n"
+                 "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"
+                 "Otherwise, press RETURN to abort...",
+                 os::current_process_id(),
+                 os::current_thread_id(), thread_self());
+
+  bool yes = os::message_box("Unexpected Error", buf);
+
+  if (yes) {
+    // yes, user asked VM to launch debugger
+    jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id());
+
+    os::fork_and_exec(buf);
+    yes = false;
+  }
+  return yes;
+}
--- a/hotspot/src/os/aix/vm/vmError_aix.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/vmError.hpp"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <signal.h>
-
-void VMError::show_message_box(char *buf, int buflen) {
-  bool yes;
-  do {
-    error_string(buf, buflen);
-    int len = (int)strlen(buf);
-    char *p = &buf[len];
-
-    jio_snprintf(p, buflen - len,
-                 "\n\n"
-                 "Do you want to debug the problem?\n\n"
-                 "To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n"
-                 "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"
-                 "Otherwise, press RETURN to abort...",
-                 os::current_process_id(),
-                 os::current_thread_id(), thread_self());
-
-    yes = os::message_box("Unexpected Error", buf);
-
-    if (yes) {
-      // yes, user asked VM to launch debugger
-      jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id());
-
-      os::fork_and_exec(buf);
-      yes = false;
-    }
-  } while (yes);
-}
-
-// Handle all synchronous signals which may happen during signal handling,
-// not just SIGSEGV and SIGBUS.
-static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
-static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
-
-// Space for our "saved" signal flags and handlers
-static int resettedSigflags[NUM_SIGNALS];
-static address resettedSighandler[NUM_SIGNALS];
-
-static void save_signal(int idx, int sig) {
-  struct sigaction sa;
-  sigaction(sig, NULL, &sa);
-  resettedSigflags[idx]   = sa.sa_flags;
-  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
-                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
-                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
-}
-
-int VMError::get_resetted_sigflags(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSigflags[i];
-    }
-  }
-  return -1;
-}
-
-address VMError::get_resetted_sighandler(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSighandler[i];
-    }
-  }
-  return NULL;
-}
-
-static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
-
-  // Unmask current signal.
-  sigset_t newset;
-  sigemptyset(&newset);
-  sigaddset(&newset, sig);
-  // and all other synchronous signals too.
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  sigthreadmask(SIG_UNBLOCK, &newset, NULL);
-
-  // support safefetch faults in error handling
-  ucontext_t* const uc = (ucontext_t*) ucVoid;
-  address const pc = uc ? os::Aix::ucontext_get_pc(uc) : NULL;
-  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
-    os::Aix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
-    return;
-  }
-
-  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
-}
-
-void VMError::reset_signal_handlers() {
-  sigset_t newset;
-  sigemptyset(&newset);
-
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    save_signal(i, SIGNALS[i]);
-    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
-    sigaddset(&newset, SIGNALS[i]);
-  }
-
-  sigthreadmask(SIG_UNBLOCK, &newset, NULL);
-}
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -3768,7 +3768,7 @@
 void os::print_statistics() {
 }
 
-int os::message_box(const char* title, const char* message) {
+bool os::message_box(const char* title, const char* message) {
   int i;
   fdStream err(defaultStream::error_fd());
   for (i = 0; i < 78; i++) err.print_raw("=");
@@ -4672,3 +4672,29 @@
   // No tests available for this platform
 }
 #endif
+
+bool os::start_debugging(char *buf, int buflen) {
+  int len = (int)strlen(buf);
+  char *p = &buf[len];
+
+  jio_snprintf(p, buflen-len,
+             "\n\n"
+             "Do you want to debug the problem?\n\n"
+             "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"
+             "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
+             "Otherwise, press RETURN to abort...",
+             os::current_process_id(), os::current_process_id(),
+             os::current_thread_id(), os::current_thread_id());
+
+  bool yes = os::message_box("Unexpected Error", buf);
+
+  if (yes) {
+    // yes, user asked VM to launch debugger
+    jio_snprintf(buf, sizeof(buf), "gdb /proc/%d/exe %d",
+                     os::current_process_id(), os::current_process_id());
+
+    os::fork_and_exec(buf);
+    yes = false;
+  }
+  return yes;
+}
--- a/hotspot/src/os/bsd/vm/vmError_bsd.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/vmError.hpp"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <signal.h>
-
-void VMError::show_message_box(char *buf, int buflen) {
-  bool yes;
-  do {
-    error_string(buf, buflen);
-    int len = (int)strlen(buf);
-    char *p = &buf[len];
-
-    jio_snprintf(p, buflen - len,
-               "\n\n"
-               "Do you want to debug the problem?\n\n"
-               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"
-               "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
-               "Otherwise, press RETURN to abort...",
-               os::current_process_id(), os::current_process_id(),
-               os::current_thread_id(), os::current_thread_id());
-
-    yes = os::message_box("Unexpected Error", buf);
-
-    if (yes) {
-      // yes, user asked VM to launch debugger
-      jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d",
-                   os::current_process_id(), os::current_process_id());
-
-      os::fork_and_exec(buf);
-      yes = false;
-    }
-  } while (yes);
-}
-
-// handle all synchronous program error signals which may happen during error
-// reporting. They must be unblocked, caught, handled.
-
-static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
-static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
-
-// Space for our "saved" signal flags and handlers
-static int resettedSigflags[NUM_SIGNALS];
-static address resettedSighandler[NUM_SIGNALS];
-
-static void save_signal(int idx, int sig)
-{
-  struct sigaction sa;
-  sigaction(sig, NULL, &sa);
-  resettedSigflags[idx]   = sa.sa_flags;
-  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
-                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
-                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
-}
-
-int VMError::get_resetted_sigflags(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSigflags[i];
-    }
-  }
-  return -1;
-}
-
-address VMError::get_resetted_sighandler(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSighandler[i];
-    }
-  }
-  return NULL;
-}
-
-static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
-  // unmask current signal
-  sigset_t newset;
-  sigemptyset(&newset);
-  sigaddset(&newset, sig);
-  // also unmask other synchronous signals
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
-
-  // support safefetch faults in error handling
-  ucontext_t* const uc = (ucontext_t*) ucVoid;
-  address const pc = uc ? os::Bsd::ucontext_get_pc(uc) : NULL;
-
-  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
-    os::Bsd::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
-    return;
-  }
-
-  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
-}
-
-void VMError::reset_signal_handlers() {
-  // install signal handlers for all synchronous program error signals
-  sigset_t newset;
-  sigemptyset(&newset);
-
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    save_signal(i, SIGNALS[i]);
-    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
-}
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -4970,7 +4970,7 @@
 void os::print_statistics() {
 }
 
-int os::message_box(const char* title, const char* message) {
+bool os::message_box(const char* title, const char* message) {
   int i;
   fdStream err(defaultStream::error_fd());
   for (i = 0; i < 78; i++) err.print_raw("=");
@@ -5995,6 +5995,34 @@
   return strlen(buffer);
 }
 
+bool os::start_debugging(char *buf, int buflen) {
+  int len = (int)strlen(buf);
+  char *p = &buf[len];
+
+  jio_snprintf(p, buflen-len,
+             "\n\n"
+             "Do you want to debug the problem?\n\n"
+             "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
+             "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
+             "Otherwise, press RETURN to abort...",
+             os::current_process_id(), os::current_process_id(),
+             os::current_thread_id(), os::current_thread_id());
+
+  bool yes = os::message_box("Unexpected Error", buf);
+
+  if (yes) {
+    // yes, user asked VM to launch debugger
+    jio_snprintf(buf, sizeof(buf), "gdb /proc/%d/exe %d",
+                     os::current_process_id(), os::current_process_id());
+
+    os::fork_and_exec(buf);
+    yes = false;
+  }
+  return yes;
+}
+
+
+
 /////////////// Unit tests ///////////////
 
 #ifndef PRODUCT
--- a/hotspot/src/os/linux/vm/vmError_linux.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/vmError.hpp"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <signal.h>
-
-void VMError::show_message_box(char *buf, int buflen) {
-  bool yes;
-  do {
-    error_string(buf, buflen);
-    int len = (int)strlen(buf);
-    char *p = &buf[len];
-
-    jio_snprintf(p, buflen - len,
-               "\n\n"
-               "Do you want to debug the problem?\n\n"
-               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
-               "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
-               "Otherwise, press RETURN to abort...",
-               os::current_process_id(), os::current_process_id(),
-               os::current_thread_id(), os::current_thread_id());
-
-    yes = os::message_box("Unexpected Error", buf);
-
-    if (yes) {
-      // yes, user asked VM to launch debugger
-      jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d",
-                   os::current_process_id(), os::current_process_id());
-
-      os::fork_and_exec(buf);
-      yes = false;
-    }
-  } while (yes);
-}
-
-// handle all synchronous program error signals which may happen during error
-// reporting. They must be unblocked, caught, handled.
-
-static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
-static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
-
-// Space for our "saved" signal flags and handlers
-static int resettedSigflags[NUM_SIGNALS];
-static address resettedSighandler[NUM_SIGNALS];
-
-static void save_signal(int idx, int sig)
-{
-  struct sigaction sa;
-  sigaction(sig, NULL, &sa);
-  resettedSigflags[idx]   = sa.sa_flags;
-  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
-                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
-                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
-}
-
-int VMError::get_resetted_sigflags(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSigflags[i];
-    }
-  }
-  return -1;
-}
-
-address VMError::get_resetted_sighandler(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSighandler[i];
-    }
-  }
-  return NULL;
-}
-
-static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
-  // unmask current signal
-  sigset_t newset;
-  sigemptyset(&newset);
-  sigaddset(&newset, sig);
-  // also unmask other synchronous signals
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
-
-  // support safefetch faults in error handling
-  ucontext_t* const uc = (ucontext_t*) ucVoid;
-  address const pc = uc ? os::Linux::ucontext_get_pc(uc) : NULL;
-
-  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
-    os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
-    return;
-  }
-
-  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
-}
-
-void VMError::reset_signal_handlers() {
-  // install signal handlers for all synchronous program error signals
-  sigset_t newset;
-  sigemptyset(&newset);
-
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    save_signal(i, SIGNALS[i]);
-    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
-
-}
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -988,6 +988,39 @@
   }
 }
 
+int os::Posix::unblock_thread_signal_mask(const sigset_t *set) {
+  return pthread_sigmask(SIG_UNBLOCK, set, NULL);
+}
+
+address os::Posix::ucontext_get_pc(ucontext_t* ctx) {
+#ifdef TARGET_OS_FAMILY_linux
+   return Linux::ucontext_get_pc(ctx);
+#elif defined(TARGET_OS_FAMILY_solaris)
+   return Solaris::ucontext_get_pc(ctx);
+#elif defined(TARGET_OS_FAMILY_aix)
+   return Aix::ucontext_get_pc(ctx);
+#elif defined(TARGET_OS_FAMILY_bsd)
+   return Bsd::ucontext_get_pc(ctx);
+#else
+   VMError::report_and_die("unimplemented ucontext_get_pc");
+#endif
+}
+
+void os::Posix::ucontext_set_pc(ucontext_t* ctx, address pc) {
+#ifdef TARGET_OS_FAMILY_linux
+   Linux::ucontext_set_pc(ctx, pc);
+#elif defined(TARGET_OS_FAMILY_solaris)
+   Solaris::ucontext_set_pc(ctx, pc);
+#elif defined(TARGET_OS_FAMILY_aix)
+   Aix::ucontext_set_pc(ctx, pc);
+#elif defined(TARGET_OS_FAMILY_bsd)
+   Bsd::ucontext_set_pc(ctx, pc);
+#else
+   VMError::report_and_die("unimplemented ucontext_get_pc");
+#endif
+}
+
+
 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
   assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
 }
--- a/hotspot/src/os/posix/vm/os_posix.hpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/posix/vm/os_posix.hpp	Wed Nov 25 16:33:28 2015 +0100
@@ -57,6 +57,9 @@
   // Prints a short one-line description of a signal set.
   static void print_signal_set_short(outputStream* st, const sigset_t* set);
 
+  // unblocks the signal masks for current thread
+  static int unblock_thread_signal_mask(const sigset_t *set);
+
   // Writes a one-line description of a combination of sigaction.sa_flags
   // into a user provided buffer. Returns that buffer.
   static const char* describe_sa_flags(int flags, char* buffer, size_t size);
@@ -67,6 +70,9 @@
   // A POSIX conform, platform-independend siginfo print routine.
   static void print_siginfo_brief(outputStream* os, const siginfo_t* si);
 
+  static address ucontext_get_pc(ucontext_t* ctx);
+  // Set PC into context. Needed for continuation after signal.
+  static void ucontext_set_pc(ucontext_t* ctx, address pc);
 };
 
 /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/posix/vm/vmError_posix.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/os.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/vmError.hpp"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#ifdef TARGET_OS_FAMILY_linux
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+#ifdef TARGET_OS_FAMILY_solaris
+#include <thread.h>
+#endif
+#ifdef TARGET_OS_FAMILY_aix
+#include <unistd.h>
+#endif
+#ifdef TARGET_OS_FAMILY_bsd
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+
+
+// handle all synchronous program error signals which may happen during error
+// reporting. They must be unblocked, caught, handled.
+
+static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
+static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
+
+// Space for our "saved" signal flags and handlers
+static int resettedSigflags[NUM_SIGNALS];
+static address resettedSighandler[NUM_SIGNALS];
+
+static void save_signal(int idx, int sig)
+{
+  struct sigaction sa;
+  sigaction(sig, NULL, &sa);
+  resettedSigflags[idx]   = sa.sa_flags;
+  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
+                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
+                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
+}
+
+int VMError::get_resetted_sigflags(int sig) {
+  for (int i = 0; i < NUM_SIGNALS; i++) {
+    if (SIGNALS[i] == sig) {
+      return resettedSigflags[i];
+    }
+  }
+  return -1;
+}
+
+address VMError::get_resetted_sighandler(int sig) {
+  for (int i = 0; i < NUM_SIGNALS; i++) {
+    if (SIGNALS[i] == sig) {
+      return resettedSighandler[i];
+    }
+  }
+  return NULL;
+}
+
+static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
+  // unmask current signal
+  sigset_t newset;
+  sigemptyset(&newset);
+  sigaddset(&newset, sig);
+  // also unmask other synchronous signals
+  for (int i = 0; i < NUM_SIGNALS; i++) {
+    sigaddset(&newset, SIGNALS[i]);
+  }
+  os::Posix::unblock_thread_signal_mask(&newset);
+
+  // support safefetch faults in error handling
+  ucontext_t* const uc = (ucontext_t*) ucVoid;
+  address const pc = uc ? os::Posix::ucontext_get_pc(uc) : NULL;
+
+  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
+    os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
+    return;
+  }
+
+  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
+}
+
+void VMError::reset_signal_handlers() {
+  // install signal handlers for all synchronous program error signals
+  sigset_t newset;
+  sigemptyset(&newset);
+
+  for (int i = 0; i < NUM_SIGNALS; i++) {
+    save_signal(i, SIGNALS[i]);
+    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
+    sigaddset(&newset, SIGNALS[i]);
+  }
+  os::Posix::unblock_thread_signal_mask(&newset);
+
+}
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -3611,7 +3611,7 @@
 void os::print_statistics() {
 }
 
-int os::message_box(const char* title, const char* message) {
+bool os::message_box(const char* title, const char* message) {
   int i;
   fdStream err(defaultStream::error_fd());
   for (i = 0; i < 78; i++) err.print_raw("=");
@@ -5804,3 +5804,27 @@
   // No tests available for this platform
 }
 #endif
+
+bool os::start_debugging(char *buf, int buflen) {
+  int len = (int)strlen(buf);
+  char *p = &buf[len];
+
+  jio_snprintf(p, buflen-len,
+               "\n\n"
+               "Do you want to debug the problem?\n\n"
+               "To debug, run 'dbx - %d'; then switch to thread " INTX_FORMAT "\n"
+               "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"
+               "Otherwise, press RETURN to abort...",
+               os::current_process_id(), os::current_thread_id());
+
+  bool yes = os::message_box("Unexpected Error", buf);
+
+  if (yes) {
+    // yes, user asked VM to launch debugger
+    jio_snprintf(buf, sizeof(buf), "dbx - %d", os::current_process_id());
+
+    os::fork_and_exec(buf);
+    yes = false;
+  }
+  return yes;
+}
--- a/hotspot/src/os/solaris/vm/vmError_solaris.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/vmError.hpp"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <thread.h>
-#include <signal.h>
-
-void VMError::show_message_box(char *buf, int buflen) {
-  bool yes;
-  do {
-    error_string(buf, buflen);
-    int len = (int)strlen(buf);
-    char *p = &buf[len];
-
-    jio_snprintf(p, buflen - len,
-               "\n\n"
-               "Do you want to debug the problem?\n\n"
-               "To debug, run 'dbx - %d'; then switch to thread " INTX_FORMAT "\n"
-               "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"
-               "Otherwise, press RETURN to abort...",
-               os::current_process_id(), os::current_thread_id());
-
-    yes = os::message_box("Unexpected Error", buf);
-
-    if (yes) {
-      // yes, user asked VM to launch debugger
-      jio_snprintf(buf, buflen, "dbx - %d", os::current_process_id());
-
-      os::fork_and_exec(buf);
-      yes = false;
-    }
-  } while (yes);
-}
-
-// handle all synchronous program error signals which may happen during error
-// reporting. They must be unblocked, caught, handled.
-
-static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
-static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
-
-// Space for our "saved" signal flags and handlers
-static int resettedSigflags[NUM_SIGNALS];
-static address resettedSighandler[NUM_SIGNALS];
-
-static void save_signal(int idx, int sig)
-{
-  struct sigaction sa;
-  sigaction(sig, NULL, &sa);
-  resettedSigflags[idx]   = sa.sa_flags;
-  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
-                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
-                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
-}
-
-int VMError::get_resetted_sigflags(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSigflags[i];
-    }
-  }
-  return -1;
-}
-
-address VMError::get_resetted_sighandler(int sig) {
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    if (SIGNALS[i] == sig) {
-      return resettedSighandler[i];
-    }
-  }
-  return NULL;
-}
-
-static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
-  // unmask current signal
-  sigset_t newset;
-  sigemptyset(&newset);
-  sigaddset(&newset, sig);
-  // also unmask other synchronous signals
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  thr_sigsetmask(SIG_UNBLOCK, &newset, NULL);
-
-  // support safefetch faults in error handling
-  ucontext_t* const uc = (ucontext_t*) ucVoid;
-  address const pc = uc ? os::Solaris::ucontext_get_pc(uc) : NULL;
-  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
-    os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
-    return;
-  }
-
-  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
-}
-
-void VMError::reset_signal_handlers() {
-  // install signal handlers for all synchronous program error signals
-  sigset_t newset;
-  sigemptyset(&newset);
-
-  for (int i = 0; i < NUM_SIGNALS; i++) {
-    save_signal(i, SIGNALS[i]);
-    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
-    sigaddset(&newset, SIGNALS[i]);
-  }
-  thr_sigsetmask(SIG_UNBLOCK, &newset, NULL);
-}
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -4005,7 +4005,7 @@
 }
 
 
-int os::message_box(const char* title, const char* message) {
+bool 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);
   return result == IDYES;
@@ -5505,7 +5505,31 @@
   }
 }
 
-
+bool os::start_debugging(char *buf, int buflen) {
+  int len = (int)strlen(buf);
+  char *p = &buf[len];
+
+  jio_snprintf(p, buflen-len,
+             "\n\n"
+             "Do you want to debug the problem?\n\n"
+             "To debug, attach Visual Studio to process %d; then switch to thread 0x%x\n"
+             "Select 'Yes' to launch Visual Studio automatically (PATH must include msdev)\n"
+             "Otherwise, select 'No' to abort...",
+             os::current_process_id(), os::current_thread_id());
+
+  bool yes = os::message_box("Unexpected Error", buf);
+
+  if (yes) {
+    // os::breakpoint() calls DebugBreak(), which causes a breakpoint
+    // exception. If VM is running inside a debugger, the debugger will
+    // catch the exception. Otherwise, the breakpoint exception will reach
+    // the default windows exception handler, which can spawn a debugger and
+    // automatically attach to the dying VM.
+    os::breakpoint();
+    yes = false;
+  }
+  return yes;
+}
 
 #ifndef JDK6_OR_EARLIER
 
--- a/hotspot/src/os/windows/vm/vmError_windows.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/os/windows/vm/vmError_windows.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -28,38 +28,6 @@
 #include "runtime/thread.hpp"
 #include "utilities/vmError.hpp"
 
-
-void VMError::show_message_box(char *buf, int buflen) {
-  bool yes;
-  do {
-    error_string(buf, buflen);
-    int len = (int)strlen(buf);
-    char *p = &buf[len];
-
-    jio_snprintf(p, buflen - len,
-               "\n\n"
-               "Do you want to debug the problem?\n\n"
-               "To debug, attach Visual Studio to process %d; then switch to thread 0x%x\n"
-               "Select 'Yes' to launch Visual Studio automatically (PATH must include msdev)\n"
-               "Otherwise, select 'No' to abort...",
-               os::current_process_id(), os::current_thread_id());
-
-    yes = os::message_box("Unexpected Error", buf) != 0;
-
-    if (yes) {
-      // yes, user asked VM to launch debugger
-      //
-      // os::breakpoint() calls DebugBreak(), which causes a breakpoint
-      // exception. If VM is running inside a debugger, the debugger will
-      // catch the exception. Otherwise, the breakpoint exception will reach
-      // the default windows exception handler, which can spawn a debugger and
-      // automatically attach to the dying VM.
-      os::breakpoint();
-      yes = false;
-    }
-  } while (yes);
-}
-
 int VMError::get_resetted_sigflags(int sig) {
   return -1;
 }
--- a/hotspot/src/share/vm/runtime/os.hpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Nov 25 16:33:28 2015 +0100
@@ -476,6 +476,7 @@
 
   static ExtendedPC get_thread_pc(Thread *thread);
   static void breakpoint();
+  static bool start_debugging(char *buf, int buflen);
 
   static address current_stack_pointer();
   static address current_stack_base();
@@ -483,7 +484,7 @@
 
   static void verify_stack_alignment() PRODUCT_RETURN;
 
-  static int message_box(const char* title, const char* message);
+  static bool message_box(const char* title, const char* message);
   static char* do_you_want_to_debug(const char* message);
 
   // run cmd in a separate process and return its exit code; or -1 on failures
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Wed Nov 18 22:00:09 2015 +0000
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Wed Nov 25 16:33:28 2015 +0100
@@ -1349,3 +1349,11 @@
     VMThread::execute(&op);
   }
 }
+
+void VMError::show_message_box(char *buf, int buflen) {
+  bool yes;
+  do {
+    error_string(buf, buflen);
+    yes = os::start_debugging(buf,buflen);
+  } while (yes);
+}