1/*
2 * Copyright (c) 2003, 2017, 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/filemap.hpp"
27#include "runtime/arguments.hpp"
28#include "runtime/os.hpp"
29#include "runtime/thread.hpp"
30#include "utilities/vmError.hpp"
31
32#include <sys/types.h>
33#include <sys/wait.h>
34#include <signal.h>
35
36#ifdef LINUX
37#include <sys/syscall.h>
38#include <unistd.h>
39#endif
40#ifdef SOLARIS
41#include <thread.h>
42#endif
43#ifdef AIX
44#include <unistd.h>
45#endif
46#ifdef BSD
47#include <sys/syscall.h>
48#include <unistd.h>
49#endif
50
51
52// handle all synchronous program error signals which may happen during error
53// reporting. They must be unblocked, caught, handled.
54
55static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
56static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
57
58// Space for our "saved" signal flags and handlers
59static int resettedSigflags[NUM_SIGNALS];
60static address resettedSighandler[NUM_SIGNALS];
61
62// Needed for cancelable steps.
63static volatile pthread_t reporter_thread_id;
64
65void VMError::reporting_started() {
66  // record pthread id of reporter thread.
67  reporter_thread_id = ::pthread_self();
68}
69
70void VMError::interrupt_reporting_thread() {
71  // We misuse SIGILL here, but it does not really matter. We need
72  //  a signal which is handled by crash_handler and not likely to
73  //  occurr during error reporting itself.
74  ::pthread_kill(reporter_thread_id, SIGILL);
75}
76
77static void save_signal(int idx, int sig)
78{
79  struct sigaction sa;
80  sigaction(sig, NULL, &sa);
81  resettedSigflags[idx]   = sa.sa_flags;
82  resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
83                              ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
84                              : CAST_FROM_FN_PTR(address, sa.sa_handler);
85}
86
87int VMError::get_resetted_sigflags(int sig) {
88  for (int i = 0; i < NUM_SIGNALS; i++) {
89    if (SIGNALS[i] == sig) {
90      return resettedSigflags[i];
91    }
92  }
93  return -1;
94}
95
96address VMError::get_resetted_sighandler(int sig) {
97  for (int i = 0; i < NUM_SIGNALS; i++) {
98    if (SIGNALS[i] == sig) {
99      return resettedSighandler[i];
100    }
101  }
102  return NULL;
103}
104
105static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
106  // unmask current signal
107  sigset_t newset;
108  sigemptyset(&newset);
109  sigaddset(&newset, sig);
110  // also unmask other synchronous signals
111  for (int i = 0; i < NUM_SIGNALS; i++) {
112    sigaddset(&newset, SIGNALS[i]);
113  }
114  os::Posix::unblock_thread_signal_mask(&newset);
115
116  // support safefetch faults in error handling
117  ucontext_t* const uc = (ucontext_t*) ucVoid;
118  address pc = (uc != NULL) ? os::Posix::ucontext_get_pc(uc) : NULL;
119
120  // Correct pc for SIGILL, SIGFPE (see JDK-8176872)
121  if (sig == SIGILL || sig == SIGFPE) {
122    pc = (address) info->si_addr;
123  }
124
125  if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
126    os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
127    return;
128  }
129
130  VMError::report_and_die(NULL, sig, pc, info, ucVoid);
131}
132
133void VMError::reset_signal_handlers() {
134  // install signal handlers for all synchronous program error signals
135  sigset_t newset;
136  sigemptyset(&newset);
137
138  for (int i = 0; i < NUM_SIGNALS; i++) {
139    save_signal(i, SIGNALS[i]);
140    os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
141    sigaddset(&newset, SIGNALS[i]);
142  }
143  os::Posix::unblock_thread_signal_mask(&newset);
144
145}
146
147// Write a hint to the stream in case siginfo relates to a segv/bus error
148// and the offending address points into CDS archive.
149void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) {
150#if INCLUDE_CDS
151  if (siginfo && UseSharedSpaces) {
152    const siginfo_t* const si = (siginfo_t*)siginfo;
153    if (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) {
154      const void* const fault_addr = si->si_addr;
155      if (fault_addr != NULL) {
156        FileMapInfo* const mapinfo = FileMapInfo::current_info();
157        if (mapinfo->is_in_shared_space(fault_addr)) {
158          st->print("Error accessing class data sharing archive. "
159            "Mapped file inaccessible during execution, possible disk/network problem.");
160        }
161      }
162    }
163  }
164#endif
165}
166
167