Fri, 05 Oct 2012 18:57:10 -0700
7177003: C1: LogCompilation support
Summary: add LogCompilation support in C1 - both client and tiered mode.
Reviewed-by: twisti, kvn
duke@435 | 1 | /* |
never@3499 | 2 | * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
stefank@2314 | 26 | #include "compiler/compileBroker.hpp" |
stefank@2314 | 27 | #include "gc_interface/collectedHeap.hpp" |
mgerdin@3619 | 28 | #include "prims/whitebox.hpp" |
stefank@2314 | 29 | #include "runtime/arguments.hpp" |
stefank@2314 | 30 | #include "runtime/frame.inline.hpp" |
stefank@2314 | 31 | #include "runtime/init.hpp" |
stefank@2314 | 32 | #include "runtime/os.hpp" |
stefank@2314 | 33 | #include "runtime/thread.hpp" |
stefank@2314 | 34 | #include "runtime/vmThread.hpp" |
stefank@2314 | 35 | #include "runtime/vm_operations.hpp" |
zgu@3900 | 36 | #include "services/memTracker.hpp" |
stefank@2314 | 37 | #include "utilities/debug.hpp" |
zgu@2364 | 38 | #include "utilities/decoder.hpp" |
stefank@2314 | 39 | #include "utilities/defaultStream.hpp" |
kamg@2515 | 40 | #include "utilities/errorReporter.hpp" |
never@3499 | 41 | #include "utilities/events.hpp" |
stefank@2314 | 42 | #include "utilities/top.hpp" |
stefank@2314 | 43 | #include "utilities/vmError.hpp" |
duke@435 | 44 | |
duke@435 | 45 | // List of environment variables that should be reported in error log file. |
duke@435 | 46 | const char *env_list[] = { |
duke@435 | 47 | // All platforms |
duke@435 | 48 | "JAVA_HOME", "JRE_HOME", "JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS", "CLASSPATH", |
duke@435 | 49 | "JAVA_COMPILER", "PATH", "USERNAME", |
duke@435 | 50 | |
never@3156 | 51 | // Env variables that are defined on Solaris/Linux/BSD |
duke@435 | 52 | "LD_LIBRARY_PATH", "LD_PRELOAD", "SHELL", "DISPLAY", |
duke@435 | 53 | "HOSTTYPE", "OSTYPE", "ARCH", "MACHTYPE", |
duke@435 | 54 | |
duke@435 | 55 | // defined on Linux |
duke@435 | 56 | "LD_ASSUME_KERNEL", "_JAVA_SR_SIGNUM", |
duke@435 | 57 | |
never@3156 | 58 | // defined on Darwin |
never@3156 | 59 | "DYLD_LIBRARY_PATH", "DYLD_FALLBACK_LIBRARY_PATH", |
never@3156 | 60 | "DYLD_FRAMEWORK_PATH", "DYLD_FALLBACK_FRAMEWORK_PATH", |
never@3156 | 61 | "DYLD_INSERT_LIBRARIES", |
never@3156 | 62 | |
duke@435 | 63 | // defined on Windows |
duke@435 | 64 | "OS", "PROCESSOR_IDENTIFIER", "_ALT_JAVA_HOME_DIR", |
duke@435 | 65 | |
duke@435 | 66 | (const char *)0 |
duke@435 | 67 | }; |
duke@435 | 68 | |
duke@435 | 69 | // Fatal error handler for internal errors and crashes. |
duke@435 | 70 | // |
duke@435 | 71 | // The default behavior of fatal error handler is to print a brief message |
duke@435 | 72 | // to standard out (defaultStream::output_fd()), then save detailed information |
duke@435 | 73 | // into an error report file (hs_err_pid<pid>.log) and abort VM. If multiple |
duke@435 | 74 | // threads are having troubles at the same time, only one error is reported. |
duke@435 | 75 | // The thread that is reporting error will abort VM when it is done, all other |
duke@435 | 76 | // threads are blocked forever inside report_and_die(). |
duke@435 | 77 | |
duke@435 | 78 | // Constructor for crashes |
coleenp@2418 | 79 | VMError::VMError(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) { |
duke@435 | 80 | _thread = thread; |
duke@435 | 81 | _id = sig; |
duke@435 | 82 | _pc = pc; |
duke@435 | 83 | _siginfo = siginfo; |
duke@435 | 84 | _context = context; |
duke@435 | 85 | |
duke@435 | 86 | _verbose = false; |
duke@435 | 87 | _current_step = 0; |
duke@435 | 88 | _current_step_info = NULL; |
duke@435 | 89 | |
jcoomes@1845 | 90 | _message = NULL; |
jcoomes@1845 | 91 | _detail_msg = NULL; |
duke@435 | 92 | _filename = NULL; |
duke@435 | 93 | _lineno = 0; |
duke@435 | 94 | |
duke@435 | 95 | _size = 0; |
duke@435 | 96 | } |
duke@435 | 97 | |
duke@435 | 98 | // Constructor for internal errors |
jcoomes@1845 | 99 | VMError::VMError(Thread* thread, const char* filename, int lineno, |
jcoomes@1845 | 100 | const char* message, const char * detail_msg) |
jcoomes@1845 | 101 | { |
jcoomes@1845 | 102 | _thread = thread; |
jcoomes@1845 | 103 | _id = internal_error; // Value that's not an OS exception/signal |
jcoomes@1845 | 104 | _filename = filename; |
jcoomes@1845 | 105 | _lineno = lineno; |
jcoomes@1845 | 106 | _message = message; |
jcoomes@1845 | 107 | _detail_msg = detail_msg; |
jcoomes@1845 | 108 | |
jcoomes@1845 | 109 | _verbose = false; |
jcoomes@1845 | 110 | _current_step = 0; |
jcoomes@1845 | 111 | _current_step_info = NULL; |
jcoomes@1845 | 112 | |
jcoomes@1845 | 113 | _pc = NULL; |
jcoomes@1845 | 114 | _siginfo = NULL; |
jcoomes@1845 | 115 | _context = NULL; |
jcoomes@1845 | 116 | |
jcoomes@1845 | 117 | _size = 0; |
jcoomes@1845 | 118 | } |
jcoomes@1845 | 119 | |
jcoomes@1845 | 120 | // Constructor for OOM errors |
jcoomes@1845 | 121 | VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size, |
jcoomes@1845 | 122 | const char* message) { |
duke@435 | 123 | _thread = thread; |
jcoomes@1845 | 124 | _id = oom_error; // Value that's not an OS exception/signal |
duke@435 | 125 | _filename = filename; |
duke@435 | 126 | _lineno = lineno; |
duke@435 | 127 | _message = message; |
jcoomes@1845 | 128 | _detail_msg = NULL; |
duke@435 | 129 | |
duke@435 | 130 | _verbose = false; |
duke@435 | 131 | _current_step = 0; |
duke@435 | 132 | _current_step_info = NULL; |
duke@435 | 133 | |
duke@435 | 134 | _pc = NULL; |
duke@435 | 135 | _siginfo = NULL; |
duke@435 | 136 | _context = NULL; |
duke@435 | 137 | |
duke@435 | 138 | _size = size; |
duke@435 | 139 | } |
duke@435 | 140 | |
duke@435 | 141 | |
duke@435 | 142 | // Constructor for non-fatal errors |
duke@435 | 143 | VMError::VMError(const char* message) { |
duke@435 | 144 | _thread = NULL; |
jcoomes@1845 | 145 | _id = internal_error; // Value that's not an OS exception/signal |
duke@435 | 146 | _filename = NULL; |
duke@435 | 147 | _lineno = 0; |
duke@435 | 148 | _message = message; |
jcoomes@1845 | 149 | _detail_msg = NULL; |
duke@435 | 150 | |
duke@435 | 151 | _verbose = false; |
duke@435 | 152 | _current_step = 0; |
duke@435 | 153 | _current_step_info = NULL; |
duke@435 | 154 | |
duke@435 | 155 | _pc = NULL; |
duke@435 | 156 | _siginfo = NULL; |
duke@435 | 157 | _context = NULL; |
duke@435 | 158 | |
duke@435 | 159 | _size = 0; |
duke@435 | 160 | } |
duke@435 | 161 | |
duke@435 | 162 | // -XX:OnError=<string>, where <string> can be a list of commands, separated |
duke@435 | 163 | // by ';'. "%p" is replaced by current process id (pid); "%%" is replaced by |
duke@435 | 164 | // a single "%". Some examples: |
duke@435 | 165 | // |
duke@435 | 166 | // -XX:OnError="pmap %p" // show memory map |
duke@435 | 167 | // -XX:OnError="gcore %p; dbx - %p" // dump core and launch debugger |
duke@435 | 168 | // -XX:OnError="cat hs_err_pid%p.log | mail my_email@sun.com" |
duke@435 | 169 | // -XX:OnError="kill -9 %p" // ?#!@# |
duke@435 | 170 | |
duke@435 | 171 | // A simple parser for -XX:OnError, usage: |
duke@435 | 172 | // ptr = OnError; |
duke@435 | 173 | // while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr) != NULL) |
duke@435 | 174 | // ... ... |
duke@435 | 175 | static char* next_OnError_command(char* buf, int buflen, const char** ptr) { |
duke@435 | 176 | if (ptr == NULL || *ptr == NULL) return NULL; |
duke@435 | 177 | |
duke@435 | 178 | const char* cmd = *ptr; |
duke@435 | 179 | |
duke@435 | 180 | // skip leading blanks or ';' |
duke@435 | 181 | while (*cmd == ' ' || *cmd == ';') cmd++; |
duke@435 | 182 | |
duke@435 | 183 | if (*cmd == '\0') return NULL; |
duke@435 | 184 | |
duke@435 | 185 | const char * cmdend = cmd; |
duke@435 | 186 | while (*cmdend != '\0' && *cmdend != ';') cmdend++; |
duke@435 | 187 | |
duke@435 | 188 | Arguments::copy_expand_pid(cmd, cmdend - cmd, buf, buflen); |
duke@435 | 189 | |
duke@435 | 190 | *ptr = (*cmdend == '\0' ? cmdend : cmdend + 1); |
duke@435 | 191 | return buf; |
duke@435 | 192 | } |
duke@435 | 193 | |
duke@435 | 194 | |
duke@435 | 195 | static void print_bug_submit_message(outputStream *out, Thread *thread) { |
duke@435 | 196 | if (out == NULL) return; |
duke@435 | 197 | out->print_raw_cr("# If you would like to submit a bug report, please visit:"); |
duke@435 | 198 | out->print_raw ("# "); |
duke@435 | 199 | out->print_raw_cr(Arguments::java_vendor_url_bug()); |
duke@435 | 200 | // If the crash is in native code, encourage user to submit a bug to the |
duke@435 | 201 | // provider of that code. |
coleenp@491 | 202 | if (thread && thread->is_Java_thread() && |
coleenp@491 | 203 | !thread->is_hidden_from_external_view()) { |
duke@435 | 204 | JavaThread* jt = (JavaThread*)thread; |
duke@435 | 205 | if (jt->thread_state() == _thread_in_native) { |
duke@435 | 206 | out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug."); |
duke@435 | 207 | } |
duke@435 | 208 | } |
duke@435 | 209 | out->print_raw_cr("#"); |
duke@435 | 210 | } |
duke@435 | 211 | |
ctornqvi@2520 | 212 | bool VMError::coredump_status; |
ctornqvi@2520 | 213 | char VMError::coredump_message[O_BUFLEN]; |
ctornqvi@2520 | 214 | |
ctornqvi@2520 | 215 | void VMError::report_coredump_status(const char* message, bool status) { |
ctornqvi@2520 | 216 | coredump_status = status; |
ctornqvi@2520 | 217 | strncpy(coredump_message, message, sizeof(coredump_message)); |
ctornqvi@2520 | 218 | coredump_message[sizeof(coredump_message)-1] = 0; |
ctornqvi@2520 | 219 | } |
ctornqvi@2520 | 220 | |
duke@435 | 221 | |
duke@435 | 222 | // Return a string to describe the error |
duke@435 | 223 | char* VMError::error_string(char* buf, int buflen) { |
duke@435 | 224 | char signame_buf[64]; |
duke@435 | 225 | const char *signame = os::exception_name(_id, signame_buf, sizeof(signame_buf)); |
duke@435 | 226 | |
duke@435 | 227 | if (signame) { |
duke@435 | 228 | jio_snprintf(buf, buflen, |
duke@435 | 229 | "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" UINTX_FORMAT, |
duke@435 | 230 | signame, _id, _pc, |
duke@435 | 231 | os::current_process_id(), os::current_thread_id()); |
jcoomes@1845 | 232 | } else if (_filename != NULL && _lineno > 0) { |
jcoomes@1845 | 233 | // skip directory names |
jcoomes@1845 | 234 | char separator = os::file_separator()[0]; |
jcoomes@1845 | 235 | const char *p = strrchr(_filename, separator); |
jcoomes@1845 | 236 | int n = jio_snprintf(buf, buflen, |
jcoomes@1845 | 237 | "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT, |
jcoomes@1845 | 238 | p ? p + 1 : _filename, _lineno, |
jcoomes@1845 | 239 | os::current_process_id(), os::current_thread_id()); |
jcoomes@1845 | 240 | if (n >= 0 && n < buflen && _message) { |
jcoomes@1845 | 241 | if (_detail_msg) { |
jcoomes@1845 | 242 | jio_snprintf(buf + n, buflen - n, "%s%s: %s", |
jcoomes@1845 | 243 | os::line_separator(), _message, _detail_msg); |
jcoomes@1845 | 244 | } else { |
jcoomes@1845 | 245 | jio_snprintf(buf + n, buflen - n, "%sError: %s", |
jcoomes@1845 | 246 | os::line_separator(), _message); |
jcoomes@1845 | 247 | } |
jcoomes@1845 | 248 | } |
duke@435 | 249 | } else { |
jcoomes@1845 | 250 | jio_snprintf(buf, buflen, |
jcoomes@1845 | 251 | "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT, |
jcoomes@1845 | 252 | _id, os::current_process_id(), os::current_thread_id()); |
duke@435 | 253 | } |
duke@435 | 254 | |
duke@435 | 255 | return buf; |
duke@435 | 256 | } |
duke@435 | 257 | |
twisti@1819 | 258 | void VMError::print_stack_trace(outputStream* st, JavaThread* jt, |
twisti@1819 | 259 | char* buf, int buflen, bool verbose) { |
twisti@1819 | 260 | #ifdef ZERO |
twisti@1819 | 261 | if (jt->zero_stack()->sp() && jt->top_zero_frame()) { |
twisti@1819 | 262 | // StackFrameStream uses the frame anchor, which may not have |
twisti@1819 | 263 | // been set up. This can be done at any time in Zero, however, |
twisti@1819 | 264 | // so if it hasn't been set up then we just set it up now and |
twisti@1819 | 265 | // clear it again when we're done. |
twisti@1819 | 266 | bool has_last_Java_frame = jt->has_last_Java_frame(); |
twisti@1819 | 267 | if (!has_last_Java_frame) |
twisti@1819 | 268 | jt->set_last_Java_frame(); |
twisti@1819 | 269 | st->print("Java frames:"); |
twisti@1819 | 270 | |
twisti@1819 | 271 | // If the top frame is a Shark frame and the frame anchor isn't |
twisti@1819 | 272 | // set up then it's possible that the information in the frame |
twisti@1819 | 273 | // is garbage: it could be from a previous decache, or it could |
twisti@1819 | 274 | // simply have never been written. So we print a warning... |
twisti@1819 | 275 | StackFrameStream sfs(jt); |
twisti@1819 | 276 | if (!has_last_Java_frame && !sfs.is_done()) { |
twisti@1819 | 277 | if (sfs.current()->zeroframe()->is_shark_frame()) { |
twisti@1819 | 278 | st->print(" (TOP FRAME MAY BE JUNK)"); |
twisti@1819 | 279 | } |
twisti@1819 | 280 | } |
twisti@1819 | 281 | st->cr(); |
twisti@1819 | 282 | |
twisti@1819 | 283 | // Print the frames |
twisti@1819 | 284 | for(int i = 0; !sfs.is_done(); sfs.next(), i++) { |
twisti@1819 | 285 | sfs.current()->zero_print_on_error(i, st, buf, buflen); |
twisti@1819 | 286 | st->cr(); |
twisti@1819 | 287 | } |
twisti@1819 | 288 | |
twisti@1819 | 289 | // Reset the frame anchor if necessary |
twisti@1819 | 290 | if (!has_last_Java_frame) |
twisti@1819 | 291 | jt->reset_last_Java_frame(); |
twisti@1819 | 292 | } |
twisti@1819 | 293 | #else |
twisti@1819 | 294 | if (jt->has_last_Java_frame()) { |
twisti@1819 | 295 | st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)"); |
twisti@1819 | 296 | for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) { |
twisti@1819 | 297 | sfs.current()->print_on_error(st, buf, buflen, verbose); |
twisti@1819 | 298 | st->cr(); |
twisti@1819 | 299 | } |
twisti@1819 | 300 | } |
twisti@1819 | 301 | #endif // ZERO |
twisti@1819 | 302 | } |
duke@435 | 303 | |
duke@435 | 304 | // This is the main function to report a fatal error. Only one thread can |
duke@435 | 305 | // call this function, so we don't need to worry about MT-safety. But it's |
duke@435 | 306 | // possible that the error handler itself may crash or die on an internal |
duke@435 | 307 | // error, for example, when the stack/heap is badly damaged. We must be |
duke@435 | 308 | // able to handle recursive errors that happen inside error handler. |
duke@435 | 309 | // |
duke@435 | 310 | // Error reporting is done in several steps. If a crash or internal error |
duke@435 | 311 | // occurred when reporting an error, the nested signal/exception handler |
duke@435 | 312 | // can skip steps that are already (or partially) done. Error reporting will |
duke@435 | 313 | // continue from the next step. This allows us to retrieve and print |
duke@435 | 314 | // information that may be unsafe to get after a fatal error. If it happens, |
duke@435 | 315 | // you may find nested report_and_die() frames when you look at the stack |
duke@435 | 316 | // in a debugger. |
duke@435 | 317 | // |
duke@435 | 318 | // In general, a hang in error handler is much worse than a crash or internal |
duke@435 | 319 | // error, as it's harder to recover from a hang. Deadlock can happen if we |
duke@435 | 320 | // try to grab a lock that is already owned by current thread, or if the |
duke@435 | 321 | // owner is blocked forever (e.g. in os::infinite_sleep()). If possible, the |
duke@435 | 322 | // error handler and all the functions it called should avoid grabbing any |
duke@435 | 323 | // lock. An important thing to notice is that memory allocation needs a lock. |
duke@435 | 324 | // |
duke@435 | 325 | // We should avoid using large stack allocated buffers. Many errors happen |
duke@435 | 326 | // when stack space is already low. Making things even worse is that there |
duke@435 | 327 | // could be nested report_and_die() calls on stack (see above). Only one |
duke@435 | 328 | // thread can report error, so large buffers are statically allocated in data |
duke@435 | 329 | // segment. |
duke@435 | 330 | |
duke@435 | 331 | void VMError::report(outputStream* st) { |
duke@435 | 332 | # define BEGIN if (_current_step == 0) { _current_step = 1; |
duke@435 | 333 | # define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s; |
duke@435 | 334 | # define END } |
duke@435 | 335 | |
duke@435 | 336 | // don't allocate large buffer on stack |
duke@435 | 337 | static char buf[O_BUFLEN]; |
duke@435 | 338 | |
duke@435 | 339 | BEGIN |
duke@435 | 340 | |
coleenp@491 | 341 | STEP(10, "(printing fatal error message)") |
duke@435 | 342 | |
coleenp@2418 | 343 | st->print_cr("#"); |
coleenp@2418 | 344 | if (should_report_bug(_id)) { |
coleenp@2418 | 345 | st->print_cr("# A fatal error has been detected by the Java Runtime Environment:"); |
coleenp@2418 | 346 | } else { |
coleenp@2418 | 347 | st->print_cr("# There is insufficient memory for the Java " |
coleenp@2418 | 348 | "Runtime Environment to continue."); |
coleenp@2418 | 349 | } |
duke@435 | 350 | |
duke@435 | 351 | STEP(15, "(printing type of error)") |
duke@435 | 352 | |
duke@435 | 353 | switch(_id) { |
duke@435 | 354 | case oom_error: |
duke@435 | 355 | if (_size) { |
coleenp@2418 | 356 | st->print("# Native memory allocation (malloc) failed to allocate "); |
coleenp@2418 | 357 | jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size); |
duke@435 | 358 | st->print(buf); |
duke@435 | 359 | st->print(" bytes"); |
duke@435 | 360 | if (_message != NULL) { |
duke@435 | 361 | st->print(" for "); |
duke@435 | 362 | st->print(_message); |
duke@435 | 363 | } |
coleenp@2418 | 364 | st->cr(); |
duke@435 | 365 | } else { |
duke@435 | 366 | if (_message != NULL) |
coleenp@2418 | 367 | st->print("# "); |
duke@435 | 368 | st->print_cr(_message); |
duke@435 | 369 | } |
coleenp@2418 | 370 | // In error file give some solutions |
coleenp@2418 | 371 | if (_verbose) { |
coleenp@2418 | 372 | st->print_cr("# Possible reasons:"); |
coleenp@2418 | 373 | st->print_cr("# The system is out of physical RAM or swap space"); |
coleenp@2418 | 374 | st->print_cr("# In 32 bit mode, the process size limit was hit"); |
coleenp@2418 | 375 | st->print_cr("# Possible solutions:"); |
coleenp@2418 | 376 | st->print_cr("# Reduce memory load on the system"); |
coleenp@2418 | 377 | st->print_cr("# Increase physical memory or swap space"); |
coleenp@2418 | 378 | st->print_cr("# Check if swap backing store is full"); |
coleenp@2418 | 379 | st->print_cr("# Use 64 bit Java on a 64 bit OS"); |
coleenp@2418 | 380 | st->print_cr("# Decrease Java heap size (-Xmx/-Xms)"); |
coleenp@2418 | 381 | st->print_cr("# Decrease number of Java threads"); |
coleenp@2418 | 382 | st->print_cr("# Decrease Java thread stack sizes (-Xss)"); |
coleenp@2418 | 383 | st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize="); |
coleenp@2418 | 384 | st->print_cr("# This output file may be truncated or incomplete."); |
coleenp@2418 | 385 | } else { |
coleenp@2418 | 386 | return; // that's enough for the screen |
coleenp@2418 | 387 | } |
duke@435 | 388 | break; |
duke@435 | 389 | case internal_error: |
duke@435 | 390 | default: |
duke@435 | 391 | break; |
duke@435 | 392 | } |
duke@435 | 393 | |
duke@435 | 394 | STEP(20, "(printing exception/signal name)") |
duke@435 | 395 | |
duke@435 | 396 | st->print_cr("#"); |
duke@435 | 397 | st->print("# "); |
duke@435 | 398 | // Is it an OS exception/signal? |
duke@435 | 399 | if (os::exception_name(_id, buf, sizeof(buf))) { |
duke@435 | 400 | st->print("%s", buf); |
duke@435 | 401 | st->print(" (0x%x)", _id); // signal number |
duke@435 | 402 | st->print(" at pc=" PTR_FORMAT, _pc); |
duke@435 | 403 | } else { |
coleenp@2418 | 404 | if (should_report_bug(_id)) { |
coleenp@2418 | 405 | st->print("Internal Error"); |
coleenp@2418 | 406 | } else { |
coleenp@2418 | 407 | st->print("Out of Memory Error"); |
coleenp@2418 | 408 | } |
duke@435 | 409 | if (_filename != NULL && _lineno > 0) { |
duke@435 | 410 | #ifdef PRODUCT |
duke@435 | 411 | // In product mode chop off pathname? |
duke@435 | 412 | char separator = os::file_separator()[0]; |
duke@435 | 413 | const char *p = strrchr(_filename, separator); |
duke@435 | 414 | const char *file = p ? p+1 : _filename; |
duke@435 | 415 | #else |
duke@435 | 416 | const char *file = _filename; |
duke@435 | 417 | #endif |
duke@435 | 418 | size_t len = strlen(file); |
duke@435 | 419 | size_t buflen = sizeof(buf); |
duke@435 | 420 | |
duke@435 | 421 | strncpy(buf, file, buflen); |
duke@435 | 422 | if (len + 10 < buflen) { |
twisti@1038 | 423 | sprintf(buf + len, ":%d", _lineno); |
duke@435 | 424 | } |
duke@435 | 425 | st->print(" (%s)", buf); |
duke@435 | 426 | } else { |
duke@435 | 427 | st->print(" (0x%x)", _id); |
duke@435 | 428 | } |
duke@435 | 429 | } |
duke@435 | 430 | |
duke@435 | 431 | STEP(30, "(printing current thread and pid)") |
duke@435 | 432 | |
duke@435 | 433 | // process id, thread id |
duke@435 | 434 | st->print(", pid=%d", os::current_process_id()); |
duke@435 | 435 | st->print(", tid=" UINTX_FORMAT, os::current_thread_id()); |
duke@435 | 436 | st->cr(); |
duke@435 | 437 | |
duke@435 | 438 | STEP(40, "(printing error message)") |
duke@435 | 439 | |
coleenp@2418 | 440 | if (should_report_bug(_id)) { // already printed the message. |
coleenp@2418 | 441 | // error message |
coleenp@2418 | 442 | if (_detail_msg) { |
coleenp@2418 | 443 | st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg); |
coleenp@2418 | 444 | } else if (_message) { |
coleenp@2418 | 445 | st->print_cr("# Error: %s", _message); |
coleenp@2418 | 446 | } |
coleenp@2418 | 447 | } |
duke@435 | 448 | |
duke@435 | 449 | STEP(50, "(printing Java version string)") |
duke@435 | 450 | |
duke@435 | 451 | // VM version |
duke@435 | 452 | st->print_cr("#"); |
coleenp@908 | 453 | JDK_Version::current().to_string(buf, sizeof(buf)); |
twisti@3884 | 454 | const char* runtime_name = JDK_Version::runtime_name() != NULL ? |
twisti@3884 | 455 | JDK_Version::runtime_name() : ""; |
twisti@3884 | 456 | st->print_cr("# JRE version: %s (%s)", runtime_name, buf); |
coleenp@548 | 457 | st->print_cr("# Java VM: %s (%s %s %s %s)", |
duke@435 | 458 | Abstract_VM_Version::vm_name(), |
duke@435 | 459 | Abstract_VM_Version::vm_release(), |
duke@435 | 460 | Abstract_VM_Version::vm_info_string(), |
coleenp@548 | 461 | Abstract_VM_Version::vm_platform_string(), |
coleenp@548 | 462 | UseCompressedOops ? "compressed oops" : "" |
duke@435 | 463 | ); |
duke@435 | 464 | |
duke@435 | 465 | STEP(60, "(printing problematic frame)") |
duke@435 | 466 | |
duke@435 | 467 | // Print current frame if we have a context (i.e. it's a crash) |
duke@435 | 468 | if (_context) { |
duke@435 | 469 | st->print_cr("# Problematic frame:"); |
duke@435 | 470 | st->print("# "); |
duke@435 | 471 | frame fr = os::fetch_frame_from_context(_context); |
duke@435 | 472 | fr.print_on_error(st, buf, sizeof(buf)); |
duke@435 | 473 | st->cr(); |
duke@435 | 474 | st->print_cr("#"); |
duke@435 | 475 | } |
ctornqvi@2520 | 476 | STEP(63, "(printing core file information)") |
ctornqvi@2520 | 477 | st->print("# "); |
ctornqvi@2520 | 478 | if (coredump_status) { |
ctornqvi@2520 | 479 | st->print("Core dump written. Default location: %s", coredump_message); |
ctornqvi@2520 | 480 | } else { |
ctornqvi@2520 | 481 | st->print("Failed to write core dump. %s", coredump_message); |
ctornqvi@2520 | 482 | } |
ctornqvi@2520 | 483 | st->print_cr(""); |
ctornqvi@2520 | 484 | st->print_cr("#"); |
duke@435 | 485 | |
duke@435 | 486 | STEP(65, "(printing bug submit message)") |
duke@435 | 487 | |
coleenp@2418 | 488 | if (should_report_bug(_id) && _verbose) { |
coleenp@2418 | 489 | print_bug_submit_message(st, _thread); |
coleenp@2418 | 490 | } |
duke@435 | 491 | |
duke@435 | 492 | STEP(70, "(printing thread)" ) |
duke@435 | 493 | |
duke@435 | 494 | if (_verbose) { |
duke@435 | 495 | st->cr(); |
duke@435 | 496 | st->print_cr("--------------- T H R E A D ---------------"); |
duke@435 | 497 | st->cr(); |
duke@435 | 498 | } |
duke@435 | 499 | |
duke@435 | 500 | STEP(80, "(printing current thread)" ) |
duke@435 | 501 | |
duke@435 | 502 | // current thread |
duke@435 | 503 | if (_verbose) { |
duke@435 | 504 | if (_thread) { |
duke@435 | 505 | st->print("Current thread (" PTR_FORMAT "): ", _thread); |
duke@435 | 506 | _thread->print_on_error(st, buf, sizeof(buf)); |
duke@435 | 507 | st->cr(); |
duke@435 | 508 | } else { |
duke@435 | 509 | st->print_cr("Current thread is native thread"); |
duke@435 | 510 | } |
duke@435 | 511 | st->cr(); |
duke@435 | 512 | } |
duke@435 | 513 | |
duke@435 | 514 | STEP(90, "(printing siginfo)" ) |
duke@435 | 515 | |
duke@435 | 516 | // signal no, signal code, address that caused the fault |
duke@435 | 517 | if (_verbose && _siginfo) { |
duke@435 | 518 | os::print_siginfo(st, _siginfo); |
duke@435 | 519 | st->cr(); |
duke@435 | 520 | } |
duke@435 | 521 | |
duke@435 | 522 | STEP(100, "(printing registers, top of stack, instructions near pc)") |
duke@435 | 523 | |
duke@435 | 524 | // registers, top of stack, instructions near pc |
duke@435 | 525 | if (_verbose && _context) { |
duke@435 | 526 | os::print_context(st, _context); |
duke@435 | 527 | st->cr(); |
duke@435 | 528 | } |
duke@435 | 529 | |
never@2262 | 530 | STEP(105, "(printing register info)") |
never@2262 | 531 | |
never@2262 | 532 | // decode register contents if possible |
never@2262 | 533 | if (_verbose && _context && Universe::is_fully_initialized()) { |
never@2262 | 534 | os::print_register_info(st, _context); |
never@2262 | 535 | st->cr(); |
never@2262 | 536 | } |
never@2262 | 537 | |
duke@435 | 538 | STEP(110, "(printing stack bounds)" ) |
duke@435 | 539 | |
duke@435 | 540 | if (_verbose) { |
duke@435 | 541 | st->print("Stack: "); |
duke@435 | 542 | |
duke@435 | 543 | address stack_top; |
duke@435 | 544 | size_t stack_size; |
duke@435 | 545 | |
duke@435 | 546 | if (_thread) { |
duke@435 | 547 | stack_top = _thread->stack_base(); |
duke@435 | 548 | stack_size = _thread->stack_size(); |
duke@435 | 549 | } else { |
duke@435 | 550 | stack_top = os::current_stack_base(); |
duke@435 | 551 | stack_size = os::current_stack_size(); |
duke@435 | 552 | } |
duke@435 | 553 | |
duke@435 | 554 | address stack_bottom = stack_top - stack_size; |
duke@435 | 555 | st->print("[" PTR_FORMAT "," PTR_FORMAT "]", stack_bottom, stack_top); |
duke@435 | 556 | |
duke@435 | 557 | frame fr = _context ? os::fetch_frame_from_context(_context) |
duke@435 | 558 | : os::current_frame(); |
duke@435 | 559 | |
duke@435 | 560 | if (fr.sp()) { |
duke@435 | 561 | st->print(", sp=" PTR_FORMAT, fr.sp()); |
kvn@2039 | 562 | size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024); |
kvn@2039 | 563 | st->print(", free space=" SIZE_FORMAT "k", free_stack_size); |
duke@435 | 564 | } |
duke@435 | 565 | |
duke@435 | 566 | st->cr(); |
duke@435 | 567 | } |
duke@435 | 568 | |
duke@435 | 569 | STEP(120, "(printing native stack)" ) |
duke@435 | 570 | |
duke@435 | 571 | if (_verbose) { |
duke@435 | 572 | frame fr = _context ? os::fetch_frame_from_context(_context) |
duke@435 | 573 | : os::current_frame(); |
duke@435 | 574 | |
duke@435 | 575 | // see if it's a valid frame |
duke@435 | 576 | if (fr.pc()) { |
duke@435 | 577 | st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); |
duke@435 | 578 | |
zgu@2364 | 579 | |
duke@435 | 580 | int count = 0; |
duke@435 | 581 | while (count++ < StackPrintLimit) { |
duke@435 | 582 | fr.print_on_error(st, buf, sizeof(buf)); |
duke@435 | 583 | st->cr(); |
duke@435 | 584 | if (os::is_first_C_frame(&fr)) break; |
duke@435 | 585 | fr = os::get_sender_for_C_frame(&fr); |
duke@435 | 586 | } |
duke@435 | 587 | |
duke@435 | 588 | if (count > StackPrintLimit) { |
duke@435 | 589 | st->print_cr("...<more frames>..."); |
duke@435 | 590 | } |
duke@435 | 591 | |
duke@435 | 592 | st->cr(); |
duke@435 | 593 | } |
duke@435 | 594 | } |
duke@435 | 595 | |
duke@435 | 596 | STEP(130, "(printing Java stack)" ) |
duke@435 | 597 | |
duke@435 | 598 | if (_verbose && _thread && _thread->is_Java_thread()) { |
twisti@1819 | 599 | print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf)); |
duke@435 | 600 | } |
duke@435 | 601 | |
minqi@1554 | 602 | STEP(135, "(printing target Java thread stack)" ) |
minqi@1554 | 603 | |
minqi@1554 | 604 | // printing Java thread stack trace if it is involved in GC crash |
never@2262 | 605 | if (_verbose && _thread && (_thread->is_Named_thread())) { |
minqi@1554 | 606 | JavaThread* jt = ((NamedThread *)_thread)->processed_thread(); |
minqi@1554 | 607 | if (jt != NULL) { |
minqi@1554 | 608 | st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id()); |
twisti@1819 | 609 | print_stack_trace(st, jt, buf, sizeof(buf), true); |
minqi@1554 | 610 | } |
minqi@1554 | 611 | } |
minqi@1554 | 612 | |
duke@435 | 613 | STEP(140, "(printing VM operation)" ) |
duke@435 | 614 | |
duke@435 | 615 | if (_verbose && _thread && _thread->is_VM_thread()) { |
duke@435 | 616 | VMThread* t = (VMThread*)_thread; |
duke@435 | 617 | VM_Operation* op = t->vm_operation(); |
duke@435 | 618 | if (op) { |
duke@435 | 619 | op->print_on_error(st); |
duke@435 | 620 | st->cr(); |
duke@435 | 621 | st->cr(); |
duke@435 | 622 | } |
duke@435 | 623 | } |
duke@435 | 624 | |
duke@435 | 625 | STEP(150, "(printing current compile task)" ) |
duke@435 | 626 | |
duke@435 | 627 | if (_verbose && _thread && _thread->is_Compiler_thread()) { |
duke@435 | 628 | CompilerThread* t = (CompilerThread*)_thread; |
duke@435 | 629 | if (t->task()) { |
duke@435 | 630 | st->cr(); |
duke@435 | 631 | st->print_cr("Current CompileTask:"); |
duke@435 | 632 | t->task()->print_line_on_error(st, buf, sizeof(buf)); |
duke@435 | 633 | st->cr(); |
duke@435 | 634 | } |
duke@435 | 635 | } |
duke@435 | 636 | |
duke@435 | 637 | STEP(160, "(printing process)" ) |
duke@435 | 638 | |
duke@435 | 639 | if (_verbose) { |
duke@435 | 640 | st->cr(); |
duke@435 | 641 | st->print_cr("--------------- P R O C E S S ---------------"); |
duke@435 | 642 | st->cr(); |
duke@435 | 643 | } |
duke@435 | 644 | |
duke@435 | 645 | STEP(170, "(printing all threads)" ) |
duke@435 | 646 | |
duke@435 | 647 | // all threads |
duke@435 | 648 | if (_verbose && _thread) { |
duke@435 | 649 | Threads::print_on_error(st, _thread, buf, sizeof(buf)); |
duke@435 | 650 | st->cr(); |
duke@435 | 651 | } |
duke@435 | 652 | |
duke@435 | 653 | STEP(175, "(printing VM state)" ) |
duke@435 | 654 | |
duke@435 | 655 | if (_verbose) { |
duke@435 | 656 | // Safepoint state |
duke@435 | 657 | st->print("VM state:"); |
duke@435 | 658 | |
duke@435 | 659 | if (SafepointSynchronize::is_synchronizing()) st->print("synchronizing"); |
duke@435 | 660 | else if (SafepointSynchronize::is_at_safepoint()) st->print("at safepoint"); |
duke@435 | 661 | else st->print("not at safepoint"); |
duke@435 | 662 | |
duke@435 | 663 | // Also see if error occurred during initialization or shutdown |
duke@435 | 664 | if (!Universe::is_fully_initialized()) { |
duke@435 | 665 | st->print(" (not fully initialized)"); |
duke@435 | 666 | } else if (VM_Exit::vm_exited()) { |
duke@435 | 667 | st->print(" (shutting down)"); |
duke@435 | 668 | } else { |
duke@435 | 669 | st->print(" (normal execution)"); |
duke@435 | 670 | } |
duke@435 | 671 | st->cr(); |
duke@435 | 672 | st->cr(); |
duke@435 | 673 | } |
duke@435 | 674 | |
duke@435 | 675 | STEP(180, "(printing owned locks on error)" ) |
duke@435 | 676 | |
duke@435 | 677 | // mutexes/monitors that currently have an owner |
duke@435 | 678 | if (_verbose) { |
duke@435 | 679 | print_owned_locks_on_error(st); |
duke@435 | 680 | st->cr(); |
duke@435 | 681 | } |
duke@435 | 682 | |
duke@435 | 683 | STEP(190, "(printing heap information)" ) |
duke@435 | 684 | |
duke@435 | 685 | if (_verbose && Universe::is_fully_initialized()) { |
tonyp@3269 | 686 | // Print heap information before vm abort. As we'd like as much |
tonyp@3269 | 687 | // information as possible in the report we ask for the |
tonyp@3269 | 688 | // extended (i.e., more detailed) version. |
tonyp@3269 | 689 | Universe::print_on(st, true /* extended */); |
duke@435 | 690 | st->cr(); |
never@3687 | 691 | |
never@3687 | 692 | Universe::heap()->barrier_set()->print_on(st); |
never@3687 | 693 | st->cr(); |
never@3687 | 694 | |
never@3687 | 695 | st->print_cr("Polling page: " INTPTR_FORMAT, os::get_polling_page()); |
never@3687 | 696 | st->cr(); |
duke@435 | 697 | } |
duke@435 | 698 | |
never@2262 | 699 | STEP(195, "(printing code cache information)" ) |
never@2262 | 700 | |
never@2262 | 701 | if (_verbose && Universe::is_fully_initialized()) { |
never@2262 | 702 | // print code cache information before vm abort |
never@2262 | 703 | CodeCache::print_bounds(st); |
never@2262 | 704 | st->cr(); |
never@2262 | 705 | } |
never@2262 | 706 | |
never@3499 | 707 | STEP(200, "(printing ring buffers)" ) |
never@3499 | 708 | |
never@3499 | 709 | if (_verbose) { |
never@3499 | 710 | Events::print_all(st); |
never@3499 | 711 | st->cr(); |
never@3499 | 712 | } |
never@3499 | 713 | |
never@3499 | 714 | STEP(205, "(printing dynamic libraries)" ) |
duke@435 | 715 | |
duke@435 | 716 | if (_verbose) { |
duke@435 | 717 | // dynamic libraries, or memory map |
duke@435 | 718 | os::print_dll_info(st); |
duke@435 | 719 | st->cr(); |
duke@435 | 720 | } |
duke@435 | 721 | |
duke@435 | 722 | STEP(210, "(printing VM options)" ) |
duke@435 | 723 | |
duke@435 | 724 | if (_verbose) { |
duke@435 | 725 | // VM options |
duke@435 | 726 | Arguments::print_on(st); |
duke@435 | 727 | st->cr(); |
duke@435 | 728 | } |
duke@435 | 729 | |
mgerdin@3619 | 730 | STEP(215, "(printing warning if internal testing API used)" ) |
mgerdin@3619 | 731 | |
mgerdin@3619 | 732 | if (WhiteBox::used()) { |
mgerdin@3619 | 733 | st->print_cr("Unsupported internal testing APIs have been used."); |
mgerdin@3619 | 734 | st->cr(); |
mgerdin@3619 | 735 | } |
mgerdin@3619 | 736 | |
duke@435 | 737 | STEP(220, "(printing environment variables)" ) |
duke@435 | 738 | |
duke@435 | 739 | if (_verbose) { |
duke@435 | 740 | os::print_environment_variables(st, env_list, buf, sizeof(buf)); |
duke@435 | 741 | st->cr(); |
duke@435 | 742 | } |
duke@435 | 743 | |
duke@435 | 744 | STEP(225, "(printing signal handlers)" ) |
duke@435 | 745 | |
duke@435 | 746 | if (_verbose) { |
duke@435 | 747 | os::print_signal_handlers(st, buf, sizeof(buf)); |
duke@435 | 748 | st->cr(); |
duke@435 | 749 | } |
duke@435 | 750 | |
duke@435 | 751 | STEP(230, "" ) |
duke@435 | 752 | |
duke@435 | 753 | if (_verbose) { |
duke@435 | 754 | st->cr(); |
duke@435 | 755 | st->print_cr("--------------- S Y S T E M ---------------"); |
duke@435 | 756 | st->cr(); |
duke@435 | 757 | } |
duke@435 | 758 | |
duke@435 | 759 | STEP(240, "(printing OS information)" ) |
duke@435 | 760 | |
duke@435 | 761 | if (_verbose) { |
duke@435 | 762 | os::print_os_info(st); |
duke@435 | 763 | st->cr(); |
duke@435 | 764 | } |
duke@435 | 765 | |
duke@435 | 766 | STEP(250, "(printing CPU info)" ) |
duke@435 | 767 | if (_verbose) { |
duke@435 | 768 | os::print_cpu_info(st); |
duke@435 | 769 | st->cr(); |
duke@435 | 770 | } |
duke@435 | 771 | |
duke@435 | 772 | STEP(260, "(printing memory info)" ) |
duke@435 | 773 | |
duke@435 | 774 | if (_verbose) { |
duke@435 | 775 | os::print_memory_info(st); |
duke@435 | 776 | st->cr(); |
duke@435 | 777 | } |
duke@435 | 778 | |
duke@435 | 779 | STEP(270, "(printing internal vm info)" ) |
duke@435 | 780 | |
duke@435 | 781 | if (_verbose) { |
duke@435 | 782 | st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string()); |
duke@435 | 783 | st->cr(); |
duke@435 | 784 | } |
duke@435 | 785 | |
duke@435 | 786 | STEP(280, "(printing date and time)" ) |
duke@435 | 787 | |
duke@435 | 788 | if (_verbose) { |
duke@435 | 789 | os::print_date_and_time(st); |
duke@435 | 790 | st->cr(); |
duke@435 | 791 | } |
duke@435 | 792 | |
duke@435 | 793 | END |
duke@435 | 794 | |
duke@435 | 795 | # undef BEGIN |
duke@435 | 796 | # undef STEP |
duke@435 | 797 | # undef END |
duke@435 | 798 | } |
duke@435 | 799 | |
bobv@2036 | 800 | VMError* volatile VMError::first_error = NULL; |
bobv@2036 | 801 | volatile jlong VMError::first_error_tid = -1; |
duke@435 | 802 | |
duke@435 | 803 | void VMError::report_and_die() { |
duke@435 | 804 | // Don't allocate large buffer on stack |
duke@435 | 805 | static char buffer[O_BUFLEN]; |
duke@435 | 806 | |
duke@435 | 807 | // An error could happen before tty is initialized or after it has been |
duke@435 | 808 | // destroyed. Here we use a very simple unbuffered fdStream for printing. |
duke@435 | 809 | // Only out.print_raw() and out.print_raw_cr() should be used, as other |
duke@435 | 810 | // printing methods need to allocate large buffer on stack. To format a |
duke@435 | 811 | // string, use jio_snprintf() with a static buffer or use staticBufferStream. |
duke@435 | 812 | static fdStream out(defaultStream::output_fd()); |
duke@435 | 813 | |
duke@435 | 814 | // How many errors occurred in error handler when reporting first_error. |
duke@435 | 815 | static int recursive_error_count; |
duke@435 | 816 | |
duke@435 | 817 | // We will first print a brief message to standard out (verbose = false), |
duke@435 | 818 | // then save detailed information in log file (verbose = true). |
duke@435 | 819 | static bool out_done = false; // done printing to standard out |
duke@435 | 820 | static bool log_done = false; // done saving error log |
kamg@2515 | 821 | static bool transmit_report_done = false; // done error reporting |
duke@435 | 822 | static fdStream log; // error log |
duke@435 | 823 | |
zgu@3900 | 824 | // disble NMT to avoid further exception |
zgu@3900 | 825 | MemTracker::shutdown(MemTracker::NMT_error_reporting); |
zgu@3900 | 826 | |
duke@435 | 827 | if (SuppressFatalErrorMessage) { |
duke@435 | 828 | os::abort(); |
duke@435 | 829 | } |
duke@435 | 830 | jlong mytid = os::current_thread_id(); |
duke@435 | 831 | if (first_error == NULL && |
duke@435 | 832 | Atomic::cmpxchg_ptr(this, &first_error, NULL) == NULL) { |
duke@435 | 833 | |
duke@435 | 834 | // first time |
duke@435 | 835 | first_error_tid = mytid; |
duke@435 | 836 | set_error_reported(); |
duke@435 | 837 | |
sla@2584 | 838 | if (ShowMessageBoxOnError || PauseAtExit) { |
duke@435 | 839 | show_message_box(buffer, sizeof(buffer)); |
duke@435 | 840 | |
duke@435 | 841 | // User has asked JVM to abort. Reset ShowMessageBoxOnError so the |
duke@435 | 842 | // WatcherThread can kill JVM if the error handler hangs. |
duke@435 | 843 | ShowMessageBoxOnError = false; |
duke@435 | 844 | } |
duke@435 | 845 | |
ctornqvi@2520 | 846 | // Write a minidump on Windows, check core dump limits on Linux/Solaris |
ctornqvi@2520 | 847 | os::check_or_create_dump(_siginfo, _context, buffer, sizeof(buffer)); |
ctornqvi@2520 | 848 | |
duke@435 | 849 | // reset signal handlers or exception filter; make sure recursive crashes |
duke@435 | 850 | // are handled properly. |
duke@435 | 851 | reset_signal_handlers(); |
duke@435 | 852 | |
duke@435 | 853 | } else { |
coleenp@946 | 854 | // If UseOsErrorReporting we call this for each level of the call stack |
coleenp@946 | 855 | // while searching for the exception handler. Only the first level needs |
coleenp@946 | 856 | // to be reported. |
coleenp@946 | 857 | if (UseOSErrorReporting && log_done) return; |
coleenp@946 | 858 | |
duke@435 | 859 | // This is not the first error, see if it happened in a different thread |
duke@435 | 860 | // or in the same thread during error reporting. |
duke@435 | 861 | if (first_error_tid != mytid) { |
duke@435 | 862 | jio_snprintf(buffer, sizeof(buffer), |
duke@435 | 863 | "[thread " INT64_FORMAT " also had an error]", |
duke@435 | 864 | mytid); |
duke@435 | 865 | out.print_raw_cr(buffer); |
duke@435 | 866 | |
duke@435 | 867 | // error reporting is not MT-safe, block current thread |
duke@435 | 868 | os::infinite_sleep(); |
duke@435 | 869 | |
duke@435 | 870 | } else { |
duke@435 | 871 | if (recursive_error_count++ > 30) { |
duke@435 | 872 | out.print_raw_cr("[Too many errors, abort]"); |
duke@435 | 873 | os::die(); |
duke@435 | 874 | } |
duke@435 | 875 | |
duke@435 | 876 | jio_snprintf(buffer, sizeof(buffer), |
duke@435 | 877 | "[error occurred during error reporting %s, id 0x%x]", |
duke@435 | 878 | first_error ? first_error->_current_step_info : "", |
duke@435 | 879 | _id); |
duke@435 | 880 | if (log.is_open()) { |
duke@435 | 881 | log.cr(); |
duke@435 | 882 | log.print_raw_cr(buffer); |
duke@435 | 883 | log.cr(); |
duke@435 | 884 | } else { |
duke@435 | 885 | out.cr(); |
duke@435 | 886 | out.print_raw_cr(buffer); |
duke@435 | 887 | out.cr(); |
duke@435 | 888 | } |
duke@435 | 889 | } |
duke@435 | 890 | } |
duke@435 | 891 | |
duke@435 | 892 | // print to screen |
duke@435 | 893 | if (!out_done) { |
duke@435 | 894 | first_error->_verbose = false; |
duke@435 | 895 | |
duke@435 | 896 | staticBufferStream sbs(buffer, sizeof(buffer), &out); |
duke@435 | 897 | first_error->report(&sbs); |
duke@435 | 898 | |
duke@435 | 899 | out_done = true; |
duke@435 | 900 | |
duke@435 | 901 | first_error->_current_step = 0; // reset current_step |
duke@435 | 902 | first_error->_current_step_info = ""; // reset current_step string |
duke@435 | 903 | } |
duke@435 | 904 | |
duke@435 | 905 | // print to error log file |
duke@435 | 906 | if (!log_done) { |
duke@435 | 907 | first_error->_verbose = true; |
duke@435 | 908 | |
duke@435 | 909 | // see if log file is already open |
duke@435 | 910 | if (!log.is_open()) { |
duke@435 | 911 | // open log file |
duke@435 | 912 | int fd = -1; |
duke@435 | 913 | |
duke@435 | 914 | if (ErrorFile != NULL) { |
duke@435 | 915 | bool copy_ok = |
duke@435 | 916 | Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); |
duke@435 | 917 | if (copy_ok) { |
kamg@2515 | 918 | fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
duke@435 | 919 | } |
duke@435 | 920 | } |
duke@435 | 921 | |
duke@435 | 922 | if (fd == -1) { |
duke@435 | 923 | const char *cwd = os::get_current_directory(buffer, sizeof(buffer)); |
duke@435 | 924 | size_t len = strlen(cwd); |
duke@435 | 925 | // either user didn't specify, or the user's location failed, |
duke@435 | 926 | // so use the default name in the current directory |
duke@435 | 927 | jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log", |
duke@435 | 928 | os::file_separator(), os::current_process_id()); |
kamg@2515 | 929 | fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
duke@435 | 930 | } |
duke@435 | 931 | |
duke@435 | 932 | if (fd == -1) { |
duke@435 | 933 | const char * tmpdir = os::get_temp_directory(); |
coleenp@2450 | 934 | // try temp directory if it exists. |
coleenp@2450 | 935 | if (tmpdir != NULL && tmpdir[0] != '\0') { |
coleenp@2450 | 936 | jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log", |
coleenp@2450 | 937 | tmpdir, os::file_separator(), os::current_process_id()); |
kamg@2515 | 938 | fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
coleenp@2450 | 939 | } |
duke@435 | 940 | } |
duke@435 | 941 | |
duke@435 | 942 | if (fd != -1) { |
duke@435 | 943 | out.print_raw("# An error report file with more information is saved as:\n# "); |
duke@435 | 944 | out.print_raw_cr(buffer); |
duke@435 | 945 | os::set_error_file(buffer); |
duke@435 | 946 | |
duke@435 | 947 | log.set_fd(fd); |
duke@435 | 948 | } else { |
duke@435 | 949 | out.print_raw_cr("# Can not save log file, dump to screen.."); |
duke@435 | 950 | log.set_fd(defaultStream::output_fd()); |
kamg@2515 | 951 | /* Error reporting currently needs dumpfile. |
kamg@2515 | 952 | * Maybe implement direct streaming in the future.*/ |
kamg@2515 | 953 | transmit_report_done = true; |
duke@435 | 954 | } |
duke@435 | 955 | } |
duke@435 | 956 | |
duke@435 | 957 | staticBufferStream sbs(buffer, O_BUFLEN, &log); |
duke@435 | 958 | first_error->report(&sbs); |
duke@435 | 959 | first_error->_current_step = 0; // reset current_step |
duke@435 | 960 | first_error->_current_step_info = ""; // reset current_step string |
duke@435 | 961 | |
kamg@2515 | 962 | // Run error reporting to determine whether or not to report the crash. |
kamg@2515 | 963 | if (!transmit_report_done && should_report_bug(first_error->_id)) { |
kamg@2515 | 964 | transmit_report_done = true; |
kamg@2515 | 965 | FILE* hs_err = ::fdopen(log.fd(), "r"); |
kamg@2515 | 966 | if (NULL != hs_err) { |
kamg@2515 | 967 | ErrorReporter er; |
kamg@2515 | 968 | er.call(hs_err, buffer, O_BUFLEN); |
kamg@2515 | 969 | } |
kamg@2515 | 970 | } |
kamg@2515 | 971 | |
duke@435 | 972 | if (log.fd() != defaultStream::output_fd()) { |
duke@435 | 973 | close(log.fd()); |
duke@435 | 974 | } |
duke@435 | 975 | |
duke@435 | 976 | log.set_fd(-1); |
duke@435 | 977 | log_done = true; |
duke@435 | 978 | } |
duke@435 | 979 | |
duke@435 | 980 | |
duke@435 | 981 | static bool skip_OnError = false; |
duke@435 | 982 | if (!skip_OnError && OnError && OnError[0]) { |
duke@435 | 983 | skip_OnError = true; |
duke@435 | 984 | |
duke@435 | 985 | out.print_raw_cr("#"); |
duke@435 | 986 | out.print_raw ("# -XX:OnError=\""); |
duke@435 | 987 | out.print_raw (OnError); |
duke@435 | 988 | out.print_raw_cr("\""); |
duke@435 | 989 | |
duke@435 | 990 | char* cmd; |
duke@435 | 991 | const char* ptr = OnError; |
duke@435 | 992 | while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ |
duke@435 | 993 | out.print_raw ("# Executing "); |
never@3156 | 994 | #if defined(LINUX) || defined(_ALLBSD_SOURCE) |
duke@435 | 995 | out.print_raw ("/bin/sh -c "); |
duke@435 | 996 | #elif defined(SOLARIS) |
duke@435 | 997 | out.print_raw ("/usr/bin/sh -c "); |
duke@435 | 998 | #endif |
duke@435 | 999 | out.print_raw ("\""); |
duke@435 | 1000 | out.print_raw (cmd); |
duke@435 | 1001 | out.print_raw_cr("\" ..."); |
duke@435 | 1002 | |
duke@435 | 1003 | os::fork_and_exec(cmd); |
duke@435 | 1004 | } |
duke@435 | 1005 | |
duke@435 | 1006 | // done with OnError |
duke@435 | 1007 | OnError = NULL; |
duke@435 | 1008 | } |
duke@435 | 1009 | |
coleenp@2418 | 1010 | static bool skip_bug_url = !should_report_bug(first_error->_id); |
duke@435 | 1011 | if (!skip_bug_url) { |
duke@435 | 1012 | skip_bug_url = true; |
duke@435 | 1013 | |
duke@435 | 1014 | out.print_raw_cr("#"); |
duke@435 | 1015 | print_bug_submit_message(&out, _thread); |
duke@435 | 1016 | } |
duke@435 | 1017 | |
duke@435 | 1018 | if (!UseOSErrorReporting) { |
duke@435 | 1019 | // os::abort() will call abort hooks, try it first. |
duke@435 | 1020 | static bool skip_os_abort = false; |
duke@435 | 1021 | if (!skip_os_abort) { |
duke@435 | 1022 | skip_os_abort = true; |
coleenp@2418 | 1023 | bool dump_core = should_report_bug(first_error->_id); |
coleenp@2418 | 1024 | os::abort(dump_core); |
duke@435 | 1025 | } |
duke@435 | 1026 | |
duke@435 | 1027 | // if os::abort() doesn't abort, try os::die(); |
duke@435 | 1028 | os::die(); |
duke@435 | 1029 | } |
duke@435 | 1030 | } |
duke@435 | 1031 | |
duke@435 | 1032 | /* |
duke@435 | 1033 | * OnOutOfMemoryError scripts/commands executed while VM is a safepoint - this |
duke@435 | 1034 | * ensures utilities such as jmap can observe the process is a consistent state. |
duke@435 | 1035 | */ |
duke@435 | 1036 | class VM_ReportJavaOutOfMemory : public VM_Operation { |
duke@435 | 1037 | private: |
duke@435 | 1038 | VMError *_err; |
duke@435 | 1039 | public: |
duke@435 | 1040 | VM_ReportJavaOutOfMemory(VMError *err) { _err = err; } |
duke@435 | 1041 | VMOp_Type type() const { return VMOp_ReportJavaOutOfMemory; } |
duke@435 | 1042 | void doit(); |
duke@435 | 1043 | }; |
duke@435 | 1044 | |
duke@435 | 1045 | void VM_ReportJavaOutOfMemory::doit() { |
duke@435 | 1046 | // Don't allocate large buffer on stack |
duke@435 | 1047 | static char buffer[O_BUFLEN]; |
duke@435 | 1048 | |
duke@435 | 1049 | tty->print_cr("#"); |
duke@435 | 1050 | tty->print_cr("# java.lang.OutOfMemoryError: %s", _err->message()); |
duke@435 | 1051 | tty->print_cr("# -XX:OnOutOfMemoryError=\"%s\"", OnOutOfMemoryError); |
duke@435 | 1052 | |
duke@435 | 1053 | // make heap parsability |
duke@435 | 1054 | Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
duke@435 | 1055 | |
duke@435 | 1056 | char* cmd; |
duke@435 | 1057 | const char* ptr = OnOutOfMemoryError; |
duke@435 | 1058 | while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ |
duke@435 | 1059 | tty->print("# Executing "); |
duke@435 | 1060 | #if defined(LINUX) |
duke@435 | 1061 | tty->print ("/bin/sh -c "); |
duke@435 | 1062 | #elif defined(SOLARIS) |
duke@435 | 1063 | tty->print ("/usr/bin/sh -c "); |
duke@435 | 1064 | #endif |
duke@435 | 1065 | tty->print_cr("\"%s\"...", cmd); |
duke@435 | 1066 | |
duke@435 | 1067 | os::fork_and_exec(cmd); |
duke@435 | 1068 | } |
duke@435 | 1069 | } |
duke@435 | 1070 | |
duke@435 | 1071 | void VMError::report_java_out_of_memory() { |
duke@435 | 1072 | if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { |
duke@435 | 1073 | MutexLocker ml(Heap_lock); |
duke@435 | 1074 | VM_ReportJavaOutOfMemory op(this); |
duke@435 | 1075 | VMThread::execute(&op); |
duke@435 | 1076 | } |
duke@435 | 1077 | } |