rev 12777 : 8176872: [s390] wrong pc shown in error logs
Reviewed-by:
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
55 static const int SIGNALS[] = { SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP }; // add more if needed
56 static const int NUM_SIGNALS = sizeof(SIGNALS) / sizeof(int);
57
58 // Space for our "saved" signal flags and handlers
59 static int resettedSigflags[NUM_SIGNALS];
60 static address resettedSighandler[NUM_SIGNALS];
61
62 // Needed for cancelable steps.
63 static volatile pthread_t reporter_thread_id;
64
65 void VMError::reporting_started() {
66 // record pthread id of reporter thread.
67 reporter_thread_id = ::pthread_self();
68 }
69
70 void 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
77 static 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
87 int 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
96 address 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
105 static 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 const pc = uc ? os::Posix::ucontext_get_pc(uc) : NULL;
119
120 if (uc && pc && StubRoutines::is_safefetch_fault(pc)) {
121 os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
122 return;
123 }
124
125 VMError::report_and_die(NULL, sig, pc, info, ucVoid);
126 }
127
128 void VMError::reset_signal_handlers() {
129 // install signal handlers for all synchronous program error signals
130 sigset_t newset;
131 sigemptyset(&newset);
132
133 for (int i = 0; i < NUM_SIGNALS; i++) {
134 save_signal(i, SIGNALS[i]);
135 os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler));
136 sigaddset(&newset, SIGNALS[i]);
137 }
138 os::Posix::unblock_thread_signal_mask(&newset);
139
140 }
141
142 // Write a hint to the stream in case siginfo relates to a segv/bus error
143 // and the offending address points into CDS archive.
144 void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) {
145 if (siginfo && UseSharedSpaces) {
146 const siginfo_t* const si = (siginfo_t*)siginfo;
147 if (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) {
148 const void* const fault_addr = si->si_addr;
149 if (fault_addr != NULL) {
150 FileMapInfo* const mapinfo = FileMapInfo::current_info();
151 if (mapinfo->is_in_shared_space(fault_addr)) {
152 st->print("Error accessing class data sharing archive. "
153 "Mapped file inaccessible during execution, possible disk/network problem.");
154 }
155 }
156 }
157 }
158 }
159
--- EOF ---