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
--- 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);
+}