1/*
2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "memory/metaspaceShared.hpp"
27#include "runtime/arguments.hpp"
28#include "runtime/os.hpp"
29#include "runtime/thread.hpp"
30#include "utilities/debug.hpp"
31#include "utilities/vmError.hpp"
32
33#include <sys/types.h>
34#include <sys/wait.h>
35#include <signal.h>
36
37#ifdef LINUX
38#include <sys/syscall.h>
39#include <unistd.h>
40#endif
41#ifdef SOLARIS
42#include <thread.h>
43#endif
44#ifdef AIX
45#include <unistd.h>
46#endif
47#ifdef BSD
48#include <sys/syscall.h>
49#include <unistd.h>
50#endif
51
52
53// handle all synchronous program error signals which may happen during error
54// reporting. They must be unblocked, caught, handled.
55
56static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
57static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
58
59// Space for our "saved" signal flags and handlers
60static int resettedSigflags[NUM_SIGNALS];
61static address resettedSighandler[NUM_SIGNALS];
62
63// Needed for cancelable steps.
64static volatile pthread_t reporter_thread_id;
65
66void VMError::reporting_started() {
67 // record pthread id of reporter thread.
68 reporter_thread_id = ::pthread_self();
69}
70
71void VMError::interrupt_reporting_thread() {
72 // We misuse SIGILL here, but it does not really matter. We need
73 // a signal which is handled by crash_handler and not likely to
74 // occurr during error reporting itself.
75 ::pthread_kill(reporter_thread_id, SIGILL);
76}
77
78static void save_signal(int idx, int sig)
79{
80 struct sigaction sa;
81 sigaction(sig, NULL, &sa);
82 resettedSigflags[idx] = sa.sa_flags;
83 resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
84 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
85 : CAST_FROM_FN_PTR(address, sa.sa_handler);
86}
87
88int VMError::get_resetted_sigflags(int sig) {
89 for (int i = 0; i < NUM_SIGNALS; i++) {
90 if (SIGNALS[i] == sig) {
91 return resettedSigflags[i];
92 }
93 }
94 return -1;
95}
96
97address VMError::get_resetted_sighandler(int sig) {
98 for (int i = 0; i < NUM_SIGNALS; i++) {
99 if (SIGNALS[i] == sig) {
100 return resettedSighandler[i];
101 }
102 }
103 return NULL;
104}
105
106static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
107 // unmask current signal
108 sigset_t newset;
109 sigemptyset(&newset);
110 sigaddset(&newset, sig);
111 // also unmask other synchronous signals
112 for (int i = 0; i < NUM_SIGNALS; i++) {
113 sigaddset(&newset, SIGNALS[i]);
114 }
115 os::Posix::unblock_thread_signal_mask(&newset);
116
117 // support safefetch faults in error handling
118 ucontext_t* const uc = (ucontext_t*) ucVoid;
119 address pc = (uc != NULL) ? os::Posix::ucontext_get_pc(uc) : NULL;
120
121 // Correct pc for SIGILL, SIGFPE (see JDK-8176872)
122 if (sig == SIGILL || sig == SIGFPE) {
123 pc = (address) info->si_addr;
124 }
125
126 // Needed to make it possible to call SafeFetch.. APIs in error handling.
127 if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
128 os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
129 return;
130 }
131
132 // Needed because asserts may happen in error handling too.
133#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
134 if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
135 handle_assert_poison_fault(ucVoid, info->si_addr);
136 return;
137 }
138#endif // CAN_SHOW_REGISTERS_ON_ASSERT
139
140 VMError::report_and_die(NULL, sig, pc, info, ucVoid);
141}
142
143void VMError::reset_signal_handlers() {
144 // install signal handlers for all synchronous program error signals
145 sigset_t newset;
146 sigemptyset(&newset);
147
148 for (int i = 0; i < NUM_SIGNALS; i++) {
149 save_signal(i, SIGNALS[i]);
150 os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
151 sigaddset(&newset, SIGNALS[i]);
152 }
153 os::Posix::unblock_thread_signal_mask(&newset);
154
155}
156
157// Write a hint to the stream in case siginfo relates to a segv/bus error
158// and the offending address points into CDS archive.
159void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) {
160#if INCLUDE_CDS
161 if (siginfo && UseSharedSpaces) {
162 const siginfo_t* const si = (siginfo_t*)siginfo;
163 if (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) {
164 const void* const fault_addr = si->si_addr;
165 if (fault_addr != NULL) {
166 if (MetaspaceShared::is_in_shared_metaspace(fault_addr)) {
167 st->print("Error accessing class data sharing archive. "
168 "Mapped file inaccessible during execution, possible disk/network problem.");
169 }
170 }
171 }
172 }
173#endif
174}
175
176