Mercurial > hg > truffle
diff src/os/posix/vm/os_posix.cpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | bb9356ec5967 |
children | 52b4284cb496 |
line wrap: on
line diff
--- a/src/os/posix/vm/os_posix.cpp Tue Apr 01 14:09:03 2014 +0200 +++ b/src/os/posix/vm/os_posix.cpp Tue Apr 01 13:57:07 2014 +0200 @@ -1,47 +1,38 @@ /* - * Copyright (c) 1999, 2014, 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. - * - */ +* Copyright (c) 1999, 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 "utilities/globalDefinitions.hpp" #include "prims/jvm.h" #include "runtime/frame.inline.hpp" -#include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "utilities/vmError.hpp" -#include <signal.h> #include <unistd.h> #include <sys/resource.h> #include <sys/utsname.h> #include <pthread.h> #include <signal.h> -// Todo: provide a os::get_max_process_id() or similar. Number of processes -// may have been configured, can be read more accurately from proc fs etc. -#ifndef MAX_PID -#define MAX_PID INT_MAX -#endif -#define IS_VALID_PID(p) (p > 0 && p < MAX_PID) // Check core dump limit and report possible place where core can be found void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { @@ -167,8 +158,8 @@ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); else st->print("%uk", rlim.rlim_cur >> 10); - // Isn't there on solaris -#if !defined(TARGET_OS_FAMILY_solaris) && !defined(TARGET_OS_FAMILY_aix) + //Isn't there on solaris +#ifndef TARGET_OS_FAMILY_solaris st->print(", NPROC "); getrlimit(RLIMIT_NPROC, &rlim); if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); @@ -271,6 +262,10 @@ return ::fdopen(fd, mode); } +void* os::get_default_process_handle() { + return (void*)::dlopen(NULL, RTLD_LAZY); +} + // Builds a platform dependent Agent_OnLoad_<lib_name> function name // which is used to find statically linked in agents. // Parameters: @@ -316,612 +311,6 @@ return agent_entry_name; } -int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - - ParkEvent * const slp = thread->_SleepEvent ; - slp->reset() ; - OrderAccess::fence() ; - - if (interruptible) { - jlong prevtime = javaTimeNanos(); - - for (;;) { - if (os::is_interrupted(thread, true)) { - return OS_INTRPT; - } - - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected in os::sleep(interruptible)"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if (millis <= 0) { - return OS_OK; - } - - prevtime = newtime; - - { - assert(thread->is_Java_thread(), "sanity check"); - JavaThread *jt = (JavaThread *) thread; - ThreadBlockInVM tbivm(jt); - OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); - - jt->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - - slp->park(millis); - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); - } - } - } else { - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); - jlong prevtime = javaTimeNanos(); - - for (;;) { - // It'd be nice to avoid the back-to-back javaTimeNanos() calls on - // the 1st iteration ... - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected on os::sleep(!interruptible)"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if (millis <= 0) break ; - - prevtime = newtime; - slp->park(millis); - } - return OS_OK ; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// interrupt support - -void os::interrupt(Thread* thread) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - if (!osthread->interrupted()) { - osthread->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); - ParkEvent * const slp = thread->_SleepEvent ; - if (slp != NULL) slp->unpark() ; - } - - // For JSR166. Unpark even if interrupt status already was set - if (thread->is_Java_thread()) - ((JavaThread*)thread)->parker()->unpark(); - - ParkEvent * ev = thread->_ParkEvent ; - if (ev != NULL) ev->unpark() ; - -} - -bool os::is_interrupted(Thread* thread, bool clear_interrupted) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - bool interrupted = osthread->interrupted(); - - // NOTE that since there is no "lock" around the interrupt and - // is_interrupted operations, there is the possibility that the - // interrupted flag (in osThread) will be "false" but that the - // low-level events will be in the signaled state. This is - // intentional. The effect of this is that Object.wait() and - // LockSupport.park() will appear to have a spurious wakeup, which - // is allowed and not harmful, and the possibility is so rare that - // it is not worth the added complexity to add yet another lock. - // For the sleep event an explicit reset is performed on entry - // to os::sleep, so there is no early return. It has also been - // recommended not to put the interrupted flag into the "event" - // structure because it hides the issue. - if (interrupted && clear_interrupted) { - osthread->set_interrupted(false); - // consider thread->_SleepEvent->reset() ... optional optimization - } - - return interrupted; -} - -// Returned string is a constant. For unknown signals "UNKNOWN" is returned. -const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) { - - static const struct { - int sig; const char* name; - } - info[] = - { - { SIGABRT, "SIGABRT" }, -#ifdef SIGAIO - { SIGAIO, "SIGAIO" }, -#endif - { SIGALRM, "SIGALRM" }, -#ifdef SIGALRM1 - { SIGALRM1, "SIGALRM1" }, -#endif - { SIGBUS, "SIGBUS" }, -#ifdef SIGCANCEL - { SIGCANCEL, "SIGCANCEL" }, -#endif - { SIGCHLD, "SIGCHLD" }, -#ifdef SIGCLD - { SIGCLD, "SIGCLD" }, -#endif - { SIGCONT, "SIGCONT" }, -#ifdef SIGCPUFAIL - { SIGCPUFAIL, "SIGCPUFAIL" }, -#endif -#ifdef SIGDANGER - { SIGDANGER, "SIGDANGER" }, -#endif -#ifdef SIGDIL - { SIGDIL, "SIGDIL" }, -#endif -#ifdef SIGEMT - { SIGEMT, "SIGEMT" }, -#endif - { SIGFPE, "SIGFPE" }, -#ifdef SIGFREEZE - { SIGFREEZE, "SIGFREEZE" }, -#endif -#ifdef SIGGFAULT - { SIGGFAULT, "SIGGFAULT" }, -#endif -#ifdef SIGGRANT - { SIGGRANT, "SIGGRANT" }, -#endif - { SIGHUP, "SIGHUP" }, - { SIGILL, "SIGILL" }, - { SIGINT, "SIGINT" }, -#ifdef SIGIO - { SIGIO, "SIGIO" }, -#endif -#ifdef SIGIOINT - { SIGIOINT, "SIGIOINT" }, -#endif -#ifdef SIGIOT - // SIGIOT is there for BSD compatibility, but on most Unices just a - // synonym for SIGABRT. The result should be "SIGABRT", not - // "SIGIOT". - #if (SIGIOT != SIGABRT ) - { SIGIOT, "SIGIOT" }, - #endif -#endif -#ifdef SIGKAP - { SIGKAP, "SIGKAP" }, -#endif - { SIGKILL, "SIGKILL" }, -#ifdef SIGLOST - { SIGLOST, "SIGLOST" }, -#endif -#ifdef SIGLWP - { SIGLWP, "SIGLWP" }, -#endif -#ifdef SIGLWPTIMER - { SIGLWPTIMER, "SIGLWPTIMER" }, -#endif -#ifdef SIGMIGRATE - { SIGMIGRATE, "SIGMIGRATE" }, -#endif -#ifdef SIGMSG - { SIGMSG, "SIGMSG" }, -#endif - { SIGPIPE, "SIGPIPE" }, -#ifdef SIGPOLL - { SIGPOLL, "SIGPOLL" }, -#endif -#ifdef SIGPRE - { SIGPRE, "SIGPRE" }, -#endif - { SIGPROF, "SIGPROF" }, -#ifdef SIGPTY - { SIGPTY, "SIGPTY" }, -#endif -#ifdef SIGPWR - { SIGPWR, "SIGPWR" }, -#endif - { SIGQUIT, "SIGQUIT" }, -#ifdef SIGRECONFIG - { SIGRECONFIG, "SIGRECONFIG" }, -#endif -#ifdef SIGRECOVERY - { SIGRECOVERY, "SIGRECOVERY" }, -#endif -#ifdef SIGRESERVE - { SIGRESERVE, "SIGRESERVE" }, -#endif -#ifdef SIGRETRACT - { SIGRETRACT, "SIGRETRACT" }, -#endif -#ifdef SIGSAK - { SIGSAK, "SIGSAK" }, -#endif - { SIGSEGV, "SIGSEGV" }, -#ifdef SIGSOUND - { SIGSOUND, "SIGSOUND" }, -#endif - { SIGSTOP, "SIGSTOP" }, - { SIGSYS, "SIGSYS" }, -#ifdef SIGSYSERROR - { SIGSYSERROR, "SIGSYSERROR" }, -#endif -#ifdef SIGTALRM - { SIGTALRM, "SIGTALRM" }, -#endif - { SIGTERM, "SIGTERM" }, -#ifdef SIGTHAW - { SIGTHAW, "SIGTHAW" }, -#endif - { SIGTRAP, "SIGTRAP" }, -#ifdef SIGTSTP - { SIGTSTP, "SIGTSTP" }, -#endif - { SIGTTIN, "SIGTTIN" }, - { SIGTTOU, "SIGTTOU" }, -#ifdef SIGURG - { SIGURG, "SIGURG" }, -#endif - { SIGUSR1, "SIGUSR1" }, - { SIGUSR2, "SIGUSR2" }, -#ifdef SIGVIRT - { SIGVIRT, "SIGVIRT" }, -#endif - { SIGVTALRM, "SIGVTALRM" }, -#ifdef SIGWAITING - { SIGWAITING, "SIGWAITING" }, -#endif -#ifdef SIGWINCH - { SIGWINCH, "SIGWINCH" }, -#endif -#ifdef SIGWINDOW - { SIGWINDOW, "SIGWINDOW" }, -#endif - { SIGXCPU, "SIGXCPU" }, - { SIGXFSZ, "SIGXFSZ" }, -#ifdef SIGXRES - { SIGXRES, "SIGXRES" }, -#endif - { -1, NULL } - }; - - const char* ret = NULL; - -#ifdef SIGRTMIN - if (sig >= SIGRTMIN && sig <= SIGRTMAX) { - if (sig == SIGRTMIN) { - ret = "SIGRTMIN"; - } else if (sig == SIGRTMAX) { - ret = "SIGRTMAX"; - } else { - jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN); - return out; - } - } -#endif - - if (sig > 0) { - for (int idx = 0; info[idx].sig != -1; idx ++) { - if (info[idx].sig == sig) { - ret = info[idx].name; - break; - } - } - } - - if (!ret) { - if (!is_valid_signal(sig)) { - ret = "INVALID"; - } else { - ret = "UNKNOWN"; - } - } - - jio_snprintf(out, outlen, ret); - return out; -} - -// Returns true if signal number is valid. -bool os::Posix::is_valid_signal(int sig) { - // MacOS not really POSIX compliant: sigaddset does not return - // an error for invalid signal numbers. However, MacOS does not - // support real time signals and simply seems to have just 33 - // signals with no holes in the signal range. -#ifdef __APPLE__ - return sig >= 1 && sig < NSIG; -#else - // Use sigaddset to check for signal validity. - sigset_t set; - if (sigaddset(&set, sig) == -1 && errno == EINVAL) { - return false; - } - return true; -#endif -} - -#define NUM_IMPORTANT_SIGS 32 -// Returns one-line short description of a signal set in a user provided buffer. -const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) { - assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size"); - // Note: for shortness, just print out the first 32. That should - // cover most of the useful ones, apart from realtime signals. - for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) { - const int rc = sigismember(set, sig); - if (rc == -1 && errno == EINVAL) { - buffer[sig-1] = '?'; - } else { - buffer[sig-1] = rc == 0 ? '0' : '1'; - } - } - buffer[NUM_IMPORTANT_SIGS] = 0; - return buffer; -} - -// Prints one-line description of a signal set. -void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { - char buf[NUM_IMPORTANT_SIGS + 1]; - os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); - st->print(buf); -} - -// Writes one-line description of a combination of sigaction.sa_flags into a user -// provided buffer. Returns that buffer. -const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { - char* p = buffer; - size_t remaining = size; - bool first = true; - int idx = 0; - - assert(buffer, "invalid argument"); - - if (size == 0) { - return buffer; - } - - strncpy(buffer, "none", size); - - const struct { - int i; - const char* s; - } flaginfo [] = { - { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, - { SA_ONSTACK, "SA_ONSTACK" }, - { SA_RESETHAND, "SA_RESETHAND" }, - { SA_RESTART, "SA_RESTART" }, - { SA_SIGINFO, "SA_SIGINFO" }, - { SA_NOCLDWAIT, "SA_NOCLDWAIT" }, - { SA_NODEFER, "SA_NODEFER" }, -#ifdef AIX - { SA_ONSTACK, "SA_ONSTACK" }, - { SA_OLDSTYLE, "SA_OLDSTYLE" }, -#endif - { 0, NULL } - }; - - for (idx = 0; flaginfo[idx].s && remaining > 1; idx++) { - if (flags & flaginfo[idx].i) { - if (first) { - jio_snprintf(p, remaining, "%s", flaginfo[idx].s); - first = false; - } else { - jio_snprintf(p, remaining, "|%s", flaginfo[idx].s); - } - const size_t len = strlen(p); - p += len; - remaining -= len; - } - } - - buffer[size - 1] = '\0'; - - return buffer; -} - -// Prints one-line description of a combination of sigaction.sa_flags. -void os::Posix::print_sa_flags(outputStream* st, int flags) { - char buffer[0x100]; - os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); - st->print(buffer); -} - -// Helper function for os::Posix::print_siginfo_...(): -// return a textual description for signal code. -struct enum_sigcode_desc_t { - const char* s_name; - const char* s_desc; -}; - -static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) { - - const struct { - int sig; int code; const char* s_code; const char* s_desc; - } t1 [] = { - { SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." }, - { SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." }, - { SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." }, - { SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." }, - { SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." }, - { SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." }, - { SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." }, - { SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." }, -#if defined(IA64) && defined(LINUX) - { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" }, - { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" }, -#endif - { SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." }, - { SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." }, - { SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." }, - { SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." }, - { SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." }, - { SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." }, - { SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." }, - { SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." }, - { SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." }, - { SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." }, -#ifdef AIX - // no explanation found what keyerr would be - { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, -#endif -#if defined(IA64) && !defined(AIX) - { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, -#endif - { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, - { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, - { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." }, - { SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." }, - { SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." }, - { SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." }, - { SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." }, - { SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." }, - { SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." }, - { SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." }, - { SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." }, -#ifdef SIGPOLL - { SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." }, - { SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." }, - { SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." }, - { SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." }, - { SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" }, -#endif - { -1, -1, NULL, NULL } - }; - - // Codes valid in any signal context. - const struct { - int code; const char* s_code; const char* s_desc; - } t2 [] = { - { SI_USER, "SI_USER", "Signal sent by kill()." }, - { SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." }, - { SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." }, - { SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." }, - { SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." }, - // Linux specific -#ifdef SI_TKILL - { SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" }, -#endif -#ifdef SI_DETHREAD - { SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" }, -#endif -#ifdef SI_KERNEL - { SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." }, -#endif -#ifdef SI_SIGIO - { SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" }, -#endif - -#ifdef AIX - { SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" }, - { SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" }, -#endif - -#ifdef __sun - { SI_NOINFO, "SI_NOINFO", "No signal information" }, - { SI_RCTL, "SI_RCTL", "kernel generated signal via rctl action" }, - { SI_LWP, "SI_LWP", "Signal sent via lwp_kill" }, -#endif - - { -1, NULL, NULL } - }; - - const char* s_code = NULL; - const char* s_desc = NULL; - - for (int i = 0; t1[i].sig != -1; i ++) { - if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) { - s_code = t1[i].s_code; - s_desc = t1[i].s_desc; - break; - } - } - - if (s_code == NULL) { - for (int i = 0; t2[i].s_code != NULL; i ++) { - if (t2[i].code == si->si_code) { - s_code = t2[i].s_code; - s_desc = t2[i].s_desc; - } - } - } - - if (s_code == NULL) { - out->s_name = "unknown"; - out->s_desc = "unknown"; - return false; - } - - out->s_name = s_code; - out->s_desc = s_desc; - - return true; -} - -// A POSIX conform, platform-independend siginfo print routine. -// Short print out on one line. -void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { - char buf[20]; - os->print("siginfo: "); - - if (!si) { - os->print("<null>"); - return; - } - - // See print_siginfo_full() for details. - const int sig = si->si_signo; - - os->print("si_signo: %d (%s)", sig, os::Posix::get_signal_name(sig, buf, sizeof(buf))); - - enum_sigcode_desc_t ed; - if (get_signal_code_description(si, &ed)) { - os->print(", si_code: %d (%s)", si->si_code, ed.s_name); - } else { - os->print(", si_code: %d (unknown)", si->si_code); - } - - if (si->si_errno) { - os->print(", si_errno: %d", si->si_errno); - } - - const int me = (int) ::getpid(); - const int pid = (int) si->si_pid; - - if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { - if (IS_VALID_PID(pid) && pid != me) { - os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid); - } - } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || - sig == SIGTRAP || sig == SIGFPE) { - os->print(", si_addr: " PTR_FORMAT, si->si_addr); -#ifdef SIGPOLL - } else if (sig == SIGPOLL) { - os->print(", si_band: " PTR64_FORMAT, (uint64_t)si->si_band); -#endif - } else if (sig == SIGCHLD) { - os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status); - } -} - os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); }