mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-01 08:12:37 +00:00
Merge
This commit is contained in:
commit
f3c2ec63b4
@ -3785,7 +3785,7 @@ os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& me
|
||||
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 @@ void TestReserveMemorySpecial_test() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -3768,7 +3768,7 @@ void os::os_exception_wrapper(java_call_t f, JavaValue* value,
|
||||
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 @@ void TestReserveMemorySpecial_test() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -4970,7 +4970,7 @@ os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& me
|
||||
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 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
|
||||
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
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -988,6 +988,39 @@ void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) {
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@ -57,6 +57,9 @@ public:
|
||||
// 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 @@ public:
|
||||
// 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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -30,35 +30,23 @@
|
||||
|
||||
#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];
|
||||
#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
|
||||
|
||||
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.
|
||||
@ -107,13 +95,14 @@ static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
|
||||
for (int i = 0; i < NUM_SIGNALS; i++) {
|
||||
sigaddset(&newset, SIGNALS[i]);
|
||||
}
|
||||
thr_sigsetmask(SIG_UNBLOCK, &newset, NULL);
|
||||
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::Solaris::ucontext_get_pc(uc) : NULL;
|
||||
address const pc = uc ? os::Posix::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));
|
||||
os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -130,5 +119,6 @@ void VMError::reset_signal_handlers() {
|
||||
os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
|
||||
sigaddset(&newset, SIGNALS[i]);
|
||||
}
|
||||
thr_sigsetmask(SIG_UNBLOCK, &newset, NULL);
|
||||
os::Posix::unblock_thread_signal_mask(&newset);
|
||||
|
||||
}
|
||||
@ -3611,7 +3611,7 @@ void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
|
||||
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 @@ void TestReserveMemorySpecial_test() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -4005,7 +4005,7 @@ void os::wait_for_keypress_at_exit(void) {
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
@ -5513,7 +5513,31 @@ void os::Kernel32Dll::initializeCommon() {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -476,6 +476,7 @@ class os: AllStatic {
|
||||
|
||||
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 @@ class os: AllStatic {
|
||||
|
||||
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
|
||||
|
||||
@ -1349,3 +1349,11 @@ void VMError::report_java_out_of_memory(const char* message) {
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user