1.1 --- a/src/os/posix/vm/os_posix.cpp Fri Aug 16 16:23:01 2013 -0700 1.2 +++ b/src/os/posix/vm/os_posix.cpp Fri Jul 26 00:59:18 2013 +0200 1.3 @@ -1,36 +1,44 @@ 1.4 /* 1.5 -* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 -* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 -* 1.8 -* This code is free software; you can redistribute it and/or modify it 1.9 -* under the terms of the GNU General Public License version 2 only, as 1.10 -* published by the Free Software Foundation. 1.11 -* 1.12 -* This code is distributed in the hope that it will be useful, but WITHOUT 1.13 -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 -* version 2 for more details (a copy is included in the LICENSE file that 1.16 -* accompanied this code). 1.17 -* 1.18 -* You should have received a copy of the GNU General Public License version 1.19 -* 2 along with this work; if not, write to the Free Software Foundation, 1.20 -* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 -* 1.22 -* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 -* or visit www.oracle.com if you need additional information or have any 1.24 -* questions. 1.25 -* 1.26 -*/ 1.27 + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.28 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.29 + * 1.30 + * This code is free software; you can redistribute it and/or modify it 1.31 + * under the terms of the GNU General Public License version 2 only, as 1.32 + * published by the Free Software Foundation. 1.33 + * 1.34 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.35 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.36 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.37 + * version 2 for more details (a copy is included in the LICENSE file that 1.38 + * accompanied this code). 1.39 + * 1.40 + * You should have received a copy of the GNU General Public License version 1.41 + * 2 along with this work; if not, write to the Free Software Foundation, 1.42 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.43 + * 1.44 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.45 + * or visit www.oracle.com if you need additional information or have any 1.46 + * questions. 1.47 + * 1.48 + */ 1.49 1.50 +#include "utilities/globalDefinitions.hpp" 1.51 #include "prims/jvm.h" 1.52 #include "runtime/frame.inline.hpp" 1.53 #include "runtime/os.hpp" 1.54 #include "utilities/vmError.hpp" 1.55 1.56 +#include <signal.h> 1.57 #include <unistd.h> 1.58 #include <sys/resource.h> 1.59 #include <sys/utsname.h> 1.60 1.61 +// Todo: provide a os::get_max_process_id() or similar. Number of processes 1.62 +// may have been configured, can be read more accurately from proc fs etc. 1.63 +#ifndef MAX_PID 1.64 +#define MAX_PID INT_MAX 1.65 +#endif 1.66 +#define IS_VALID_PID(p) (p > 0 && p < MAX_PID) 1.67 1.68 // Check core dump limit and report possible place where core can be found 1.69 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { 1.70 @@ -156,7 +164,7 @@ 1.71 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); 1.72 else st->print("%uk", rlim.rlim_cur >> 10); 1.73 1.74 - //Isn't there on solaris 1.75 + // Isn't there on solaris 1.76 #ifndef TARGET_OS_FAMILY_solaris 1.77 st->print(", NPROC "); 1.78 getrlimit(RLIMIT_NPROC, &rlim); 1.79 @@ -260,6 +268,484 @@ 1.80 return ::fdopen(fd, mode); 1.81 } 1.82 1.83 + 1.84 +// Returned string is a constant. For unknown signals "UNKNOWN" is returned. 1.85 +const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) { 1.86 + 1.87 + static const struct { 1.88 + int sig; const char* name; 1.89 + } 1.90 + info[] = 1.91 + { 1.92 + { SIGABRT, "SIGABRT" }, 1.93 +#ifdef SIGAIO 1.94 + { SIGAIO, "SIGAIO" }, 1.95 +#endif 1.96 + { SIGALRM, "SIGALRM" }, 1.97 +#ifdef SIGALRM1 1.98 + { SIGALRM1, "SIGALRM1" }, 1.99 +#endif 1.100 + { SIGBUS, "SIGBUS" }, 1.101 +#ifdef SIGCANCEL 1.102 + { SIGCANCEL, "SIGCANCEL" }, 1.103 +#endif 1.104 + { SIGCHLD, "SIGCHLD" }, 1.105 +#ifdef SIGCLD 1.106 + { SIGCLD, "SIGCLD" }, 1.107 +#endif 1.108 + { SIGCONT, "SIGCONT" }, 1.109 +#ifdef SIGCPUFAIL 1.110 + { SIGCPUFAIL, "SIGCPUFAIL" }, 1.111 +#endif 1.112 +#ifdef SIGDANGER 1.113 + { SIGDANGER, "SIGDANGER" }, 1.114 +#endif 1.115 +#ifdef SIGDIL 1.116 + { SIGDIL, "SIGDIL" }, 1.117 +#endif 1.118 +#ifdef SIGEMT 1.119 + { SIGEMT, "SIGEMT" }, 1.120 +#endif 1.121 + { SIGFPE, "SIGFPE" }, 1.122 +#ifdef SIGFREEZE 1.123 + { SIGFREEZE, "SIGFREEZE" }, 1.124 +#endif 1.125 +#ifdef SIGGFAULT 1.126 + { SIGGFAULT, "SIGGFAULT" }, 1.127 +#endif 1.128 +#ifdef SIGGRANT 1.129 + { SIGGRANT, "SIGGRANT" }, 1.130 +#endif 1.131 + { SIGHUP, "SIGHUP" }, 1.132 + { SIGILL, "SIGILL" }, 1.133 + { SIGINT, "SIGINT" }, 1.134 +#ifdef SIGIO 1.135 + { SIGIO, "SIGIO" }, 1.136 +#endif 1.137 +#ifdef SIGIOINT 1.138 + { SIGIOINT, "SIGIOINT" }, 1.139 +#endif 1.140 +#ifdef SIGIOT 1.141 + // SIGIOT is there for BSD compatibility, but on most Unices just a 1.142 + // synonym for SIGABRT. The result should be "SIGABRT", not 1.143 + // "SIGIOT". 1.144 + #if (SIGIOT != SIGABRT ) 1.145 + { SIGIOT, "SIGIOT" }, 1.146 + #endif 1.147 +#endif 1.148 +#ifdef SIGKAP 1.149 + { SIGKAP, "SIGKAP" }, 1.150 +#endif 1.151 + { SIGKILL, "SIGKILL" }, 1.152 +#ifdef SIGLOST 1.153 + { SIGLOST, "SIGLOST" }, 1.154 +#endif 1.155 +#ifdef SIGLWP 1.156 + { SIGLWP, "SIGLWP" }, 1.157 +#endif 1.158 +#ifdef SIGLWPTIMER 1.159 + { SIGLWPTIMER, "SIGLWPTIMER" }, 1.160 +#endif 1.161 +#ifdef SIGMIGRATE 1.162 + { SIGMIGRATE, "SIGMIGRATE" }, 1.163 +#endif 1.164 +#ifdef SIGMSG 1.165 + { SIGMSG, "SIGMSG" }, 1.166 +#endif 1.167 + { SIGPIPE, "SIGPIPE" }, 1.168 +#ifdef SIGPOLL 1.169 + { SIGPOLL, "SIGPOLL" }, 1.170 +#endif 1.171 +#ifdef SIGPRE 1.172 + { SIGPRE, "SIGPRE" }, 1.173 +#endif 1.174 + { SIGPROF, "SIGPROF" }, 1.175 +#ifdef SIGPTY 1.176 + { SIGPTY, "SIGPTY" }, 1.177 +#endif 1.178 +#ifdef SIGPWR 1.179 + { SIGPWR, "SIGPWR" }, 1.180 +#endif 1.181 + { SIGQUIT, "SIGQUIT" }, 1.182 +#ifdef SIGRECONFIG 1.183 + { SIGRECONFIG, "SIGRECONFIG" }, 1.184 +#endif 1.185 +#ifdef SIGRECOVERY 1.186 + { SIGRECOVERY, "SIGRECOVERY" }, 1.187 +#endif 1.188 +#ifdef SIGRESERVE 1.189 + { SIGRESERVE, "SIGRESERVE" }, 1.190 +#endif 1.191 +#ifdef SIGRETRACT 1.192 + { SIGRETRACT, "SIGRETRACT" }, 1.193 +#endif 1.194 +#ifdef SIGSAK 1.195 + { SIGSAK, "SIGSAK" }, 1.196 +#endif 1.197 + { SIGSEGV, "SIGSEGV" }, 1.198 +#ifdef SIGSOUND 1.199 + { SIGSOUND, "SIGSOUND" }, 1.200 +#endif 1.201 + { SIGSTOP, "SIGSTOP" }, 1.202 + { SIGSYS, "SIGSYS" }, 1.203 +#ifdef SIGSYSERROR 1.204 + { SIGSYSERROR, "SIGSYSERROR" }, 1.205 +#endif 1.206 +#ifdef SIGTALRM 1.207 + { SIGTALRM, "SIGTALRM" }, 1.208 +#endif 1.209 + { SIGTERM, "SIGTERM" }, 1.210 +#ifdef SIGTHAW 1.211 + { SIGTHAW, "SIGTHAW" }, 1.212 +#endif 1.213 + { SIGTRAP, "SIGTRAP" }, 1.214 +#ifdef SIGTSTP 1.215 + { SIGTSTP, "SIGTSTP" }, 1.216 +#endif 1.217 + { SIGTTIN, "SIGTTIN" }, 1.218 + { SIGTTOU, "SIGTTOU" }, 1.219 +#ifdef SIGURG 1.220 + { SIGURG, "SIGURG" }, 1.221 +#endif 1.222 + { SIGUSR1, "SIGUSR1" }, 1.223 + { SIGUSR2, "SIGUSR2" }, 1.224 +#ifdef SIGVIRT 1.225 + { SIGVIRT, "SIGVIRT" }, 1.226 +#endif 1.227 + { SIGVTALRM, "SIGVTALRM" }, 1.228 +#ifdef SIGWAITING 1.229 + { SIGWAITING, "SIGWAITING" }, 1.230 +#endif 1.231 +#ifdef SIGWINCH 1.232 + { SIGWINCH, "SIGWINCH" }, 1.233 +#endif 1.234 +#ifdef SIGWINDOW 1.235 + { SIGWINDOW, "SIGWINDOW" }, 1.236 +#endif 1.237 + { SIGXCPU, "SIGXCPU" }, 1.238 + { SIGXFSZ, "SIGXFSZ" }, 1.239 +#ifdef SIGXRES 1.240 + { SIGXRES, "SIGXRES" }, 1.241 +#endif 1.242 + { -1, NULL } 1.243 + }; 1.244 + 1.245 + const char* ret = NULL; 1.246 + 1.247 +#ifdef SIGRTMIN 1.248 + if (sig >= SIGRTMIN && sig <= SIGRTMAX) { 1.249 + if (sig == SIGRTMIN) { 1.250 + ret = "SIGRTMIN"; 1.251 + } else if (sig == SIGRTMAX) { 1.252 + ret = "SIGRTMAX"; 1.253 + } else { 1.254 + jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN); 1.255 + return out; 1.256 + } 1.257 + } 1.258 +#endif 1.259 + 1.260 + if (sig > 0) { 1.261 + for (int idx = 0; info[idx].sig != -1; idx ++) { 1.262 + if (info[idx].sig == sig) { 1.263 + ret = info[idx].name; 1.264 + break; 1.265 + } 1.266 + } 1.267 + } 1.268 + 1.269 + if (!ret) { 1.270 + if (!is_valid_signal(sig)) { 1.271 + ret = "INVALID"; 1.272 + } else { 1.273 + ret = "UNKNOWN"; 1.274 + } 1.275 + } 1.276 + 1.277 + jio_snprintf(out, outlen, ret); 1.278 + return out; 1.279 +} 1.280 + 1.281 +// Returns true if signal number is valid. 1.282 +bool os::Posix::is_valid_signal(int sig) { 1.283 + // MacOS not really POSIX compliant: sigaddset does not return 1.284 + // an error for invalid signal numbers. However, MacOS does not 1.285 + // support real time signals and simply seems to have just 33 1.286 + // signals with no holes in the signal range. 1.287 +#ifdef __APPLE__ 1.288 + return sig >= 1 && sig < NSIG; 1.289 +#else 1.290 + // Use sigaddset to check for signal validity. 1.291 + sigset_t set; 1.292 + if (sigaddset(&set, sig) == -1 && errno == EINVAL) { 1.293 + return false; 1.294 + } 1.295 + return true; 1.296 +#endif 1.297 +} 1.298 + 1.299 +#define NUM_IMPORTANT_SIGS 32 1.300 +// Returns one-line short description of a signal set in a user provided buffer. 1.301 +const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) { 1.302 + assert(buf_size = (NUM_IMPORTANT_SIGS + 1), "wrong buffer size"); 1.303 + // Note: for shortness, just print out the first 32. That should 1.304 + // cover most of the useful ones, apart from realtime signals. 1.305 + for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) { 1.306 + const int rc = sigismember(set, sig); 1.307 + if (rc == -1 && errno == EINVAL) { 1.308 + buffer[sig-1] = '?'; 1.309 + } else { 1.310 + buffer[sig-1] = rc == 0 ? '0' : '1'; 1.311 + } 1.312 + } 1.313 + buffer[NUM_IMPORTANT_SIGS] = 0; 1.314 + return buffer; 1.315 +} 1.316 + 1.317 +// Prints one-line description of a signal set. 1.318 +void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { 1.319 + char buf[NUM_IMPORTANT_SIGS + 1]; 1.320 + os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); 1.321 + st->print(buf); 1.322 +} 1.323 + 1.324 +// Writes one-line description of a combination of sigaction.sa_flags into a user 1.325 +// provided buffer. Returns that buffer. 1.326 +const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { 1.327 + char* p = buffer; 1.328 + size_t remaining = size; 1.329 + bool first = true; 1.330 + int idx = 0; 1.331 + 1.332 + assert(buffer, "invalid argument"); 1.333 + 1.334 + if (size == 0) { 1.335 + return buffer; 1.336 + } 1.337 + 1.338 + strncpy(buffer, "none", size); 1.339 + 1.340 + const struct { 1.341 + int i; 1.342 + const char* s; 1.343 + } flaginfo [] = { 1.344 + { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, 1.345 + { SA_ONSTACK, "SA_ONSTACK" }, 1.346 + { SA_RESETHAND, "SA_RESETHAND" }, 1.347 + { SA_RESTART, "SA_RESTART" }, 1.348 + { SA_SIGINFO, "SA_SIGINFO" }, 1.349 + { SA_NOCLDWAIT, "SA_NOCLDWAIT" }, 1.350 + { SA_NODEFER, "SA_NODEFER" }, 1.351 +#ifdef AIX 1.352 + { SA_ONSTACK, "SA_ONSTACK" }, 1.353 + { SA_OLDSTYLE, "SA_OLDSTYLE" }, 1.354 +#endif 1.355 + { 0, NULL } 1.356 + }; 1.357 + 1.358 + for (idx = 0; flaginfo[idx].s && remaining > 1; idx++) { 1.359 + if (flags & flaginfo[idx].i) { 1.360 + if (first) { 1.361 + jio_snprintf(p, remaining, "%s", flaginfo[idx].s); 1.362 + first = false; 1.363 + } else { 1.364 + jio_snprintf(p, remaining, "|%s", flaginfo[idx].s); 1.365 + } 1.366 + const size_t len = strlen(p); 1.367 + p += len; 1.368 + remaining -= len; 1.369 + } 1.370 + } 1.371 + 1.372 + buffer[size - 1] = '\0'; 1.373 + 1.374 + return buffer; 1.375 +} 1.376 + 1.377 +// Prints one-line description of a combination of sigaction.sa_flags. 1.378 +void os::Posix::print_sa_flags(outputStream* st, int flags) { 1.379 + char buffer[0x100]; 1.380 + os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); 1.381 + st->print(buffer); 1.382 +} 1.383 + 1.384 +// Helper function for os::Posix::print_siginfo_...(): 1.385 +// return a textual description for signal code. 1.386 +struct enum_sigcode_desc_t { 1.387 + const char* s_name; 1.388 + const char* s_desc; 1.389 +}; 1.390 + 1.391 +static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) { 1.392 + 1.393 + const struct { 1.394 + int sig; int code; const char* s_code; const char* s_desc; 1.395 + } t1 [] = { 1.396 + { SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." }, 1.397 + { SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." }, 1.398 + { SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." }, 1.399 + { SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." }, 1.400 + { SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." }, 1.401 + { SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." }, 1.402 + { SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." }, 1.403 + { SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." }, 1.404 +#if defined(IA64) && defined(LINUX) 1.405 + { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" }, 1.406 + { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" }, 1.407 +#endif 1.408 + { SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." }, 1.409 + { SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." }, 1.410 + { SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." }, 1.411 + { SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." }, 1.412 + { SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." }, 1.413 + { SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." }, 1.414 + { SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." }, 1.415 + { SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." }, 1.416 + { SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." }, 1.417 + { SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." }, 1.418 +#ifdef AIX 1.419 + // no explanation found what keyerr would be 1.420 + { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, 1.421 +#endif 1.422 +#if defined(IA64) && !defined(AIX) 1.423 + { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, 1.424 +#endif 1.425 + { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, 1.426 + { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, 1.427 + { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." }, 1.428 + { SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." }, 1.429 + { SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." }, 1.430 + { SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." }, 1.431 + { SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." }, 1.432 + { SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." }, 1.433 + { SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." }, 1.434 + { SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." }, 1.435 + { SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." }, 1.436 +#ifdef SIGPOLL 1.437 + { SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." }, 1.438 + { SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." }, 1.439 + { SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." }, 1.440 + { SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." }, 1.441 + { SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" }, 1.442 +#endif 1.443 + { -1, -1, NULL, NULL } 1.444 + }; 1.445 + 1.446 + // Codes valid in any signal context. 1.447 + const struct { 1.448 + int code; const char* s_code; const char* s_desc; 1.449 + } t2 [] = { 1.450 + { SI_USER, "SI_USER", "Signal sent by kill()." }, 1.451 + { SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." }, 1.452 + { SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." }, 1.453 + { SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." }, 1.454 + { SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." }, 1.455 + // Linux specific 1.456 +#ifdef SI_TKILL 1.457 + { SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" }, 1.458 +#endif 1.459 +#ifdef SI_DETHREAD 1.460 + { SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" }, 1.461 +#endif 1.462 +#ifdef SI_KERNEL 1.463 + { SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." }, 1.464 +#endif 1.465 +#ifdef SI_SIGIO 1.466 + { SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" }, 1.467 +#endif 1.468 + 1.469 +#ifdef AIX 1.470 + { SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" }, 1.471 + { SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" }, 1.472 +#endif 1.473 + 1.474 +#ifdef __sun 1.475 + { SI_NOINFO, "SI_NOINFO", "No signal information" }, 1.476 + { SI_RCTL, "SI_RCTL", "kernel generated signal via rctl action" }, 1.477 + { SI_LWP, "SI_LWP", "Signal sent via lwp_kill" }, 1.478 +#endif 1.479 + 1.480 + { -1, NULL, NULL } 1.481 + }; 1.482 + 1.483 + const char* s_code = NULL; 1.484 + const char* s_desc = NULL; 1.485 + 1.486 + for (int i = 0; t1[i].sig != -1; i ++) { 1.487 + if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) { 1.488 + s_code = t1[i].s_code; 1.489 + s_desc = t1[i].s_desc; 1.490 + break; 1.491 + } 1.492 + } 1.493 + 1.494 + if (s_code == NULL) { 1.495 + for (int i = 0; t2[i].s_code != NULL; i ++) { 1.496 + if (t2[i].code == si->si_code) { 1.497 + s_code = t2[i].s_code; 1.498 + s_desc = t2[i].s_desc; 1.499 + } 1.500 + } 1.501 + } 1.502 + 1.503 + if (s_code == NULL) { 1.504 + out->s_name = "unknown"; 1.505 + out->s_desc = "unknown"; 1.506 + return false; 1.507 + } 1.508 + 1.509 + out->s_name = s_code; 1.510 + out->s_desc = s_desc; 1.511 + 1.512 + return true; 1.513 +} 1.514 + 1.515 +// A POSIX conform, platform-independend siginfo print routine. 1.516 +// Short print out on one line. 1.517 +void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { 1.518 + char buf[20]; 1.519 + os->print("siginfo: "); 1.520 + 1.521 + if (!si) { 1.522 + os->print("<null>"); 1.523 + return; 1.524 + } 1.525 + 1.526 + // See print_siginfo_full() for details. 1.527 + const int sig = si->si_signo; 1.528 + 1.529 + os->print("si_signo: %d (%s)", sig, os::Posix::get_signal_name(sig, buf, sizeof(buf))); 1.530 + 1.531 + enum_sigcode_desc_t ed; 1.532 + if (get_signal_code_description(si, &ed)) { 1.533 + os->print(", si_code: %d (%s)", si->si_code, ed.s_name); 1.534 + } else { 1.535 + os->print(", si_code: %d (unknown)", si->si_code); 1.536 + } 1.537 + 1.538 + if (si->si_errno) { 1.539 + os->print(", si_errno: %d", si->si_errno); 1.540 + } 1.541 + 1.542 + const int me = (int) ::getpid(); 1.543 + const int pid = (int) si->si_pid; 1.544 + 1.545 + if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { 1.546 + if (IS_VALID_PID(pid) && pid != me) { 1.547 + os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid); 1.548 + } 1.549 + } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || 1.550 + sig == SIGTRAP || sig == SIGFPE) { 1.551 + os->print(", si_addr: " PTR_FORMAT, si->si_addr); 1.552 +#ifdef SIGPOLL 1.553 + } else if (sig == SIGPOLL) { 1.554 + os->print(", si_band: " PTR64_FORMAT, (uint64_t)si->si_band); 1.555 +#endif 1.556 + } else if (sig == SIGCHLD) { 1.557 + os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status); 1.558 + } 1.559 +} 1.560 + 1.561 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 1.562 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 1.563 }