Thu, 25 Apr 2013 11:02:32 -0700
8012260: ciReplay: Include PID into the name of replay data file
Reviewed-by: kvn, twisti
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() : ""; |
sla@4232 | 456 | const char* runtime_version = JDK_Version::runtime_version() != NULL ? |
sla@4232 | 457 | JDK_Version::runtime_version() : ""; |
sla@4232 | 458 | st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version); |
coleenp@548 | 459 | st->print_cr("# Java VM: %s (%s %s %s %s)", |
duke@435 | 460 | Abstract_VM_Version::vm_name(), |
duke@435 | 461 | Abstract_VM_Version::vm_release(), |
duke@435 | 462 | Abstract_VM_Version::vm_info_string(), |
coleenp@548 | 463 | Abstract_VM_Version::vm_platform_string(), |
coleenp@548 | 464 | UseCompressedOops ? "compressed oops" : "" |
duke@435 | 465 | ); |
duke@435 | 466 | |
duke@435 | 467 | STEP(60, "(printing problematic frame)") |
duke@435 | 468 | |
duke@435 | 469 | // Print current frame if we have a context (i.e. it's a crash) |
duke@435 | 470 | if (_context) { |
duke@435 | 471 | st->print_cr("# Problematic frame:"); |
duke@435 | 472 | st->print("# "); |
duke@435 | 473 | frame fr = os::fetch_frame_from_context(_context); |
duke@435 | 474 | fr.print_on_error(st, buf, sizeof(buf)); |
duke@435 | 475 | st->cr(); |
duke@435 | 476 | st->print_cr("#"); |
duke@435 | 477 | } |
ctornqvi@2520 | 478 | STEP(63, "(printing core file information)") |
ctornqvi@2520 | 479 | st->print("# "); |
ctornqvi@2520 | 480 | if (coredump_status) { |
ctornqvi@2520 | 481 | st->print("Core dump written. Default location: %s", coredump_message); |
ctornqvi@2520 | 482 | } else { |
ctornqvi@2520 | 483 | st->print("Failed to write core dump. %s", coredump_message); |
ctornqvi@2520 | 484 | } |
ctornqvi@2520 | 485 | st->print_cr(""); |
ctornqvi@2520 | 486 | st->print_cr("#"); |
duke@435 | 487 | |
duke@435 | 488 | STEP(65, "(printing bug submit message)") |
duke@435 | 489 | |
coleenp@2418 | 490 | if (should_report_bug(_id) && _verbose) { |
coleenp@2418 | 491 | print_bug_submit_message(st, _thread); |
coleenp@2418 | 492 | } |
duke@435 | 493 | |
duke@435 | 494 | STEP(70, "(printing thread)" ) |
duke@435 | 495 | |
duke@435 | 496 | if (_verbose) { |
duke@435 | 497 | st->cr(); |
duke@435 | 498 | st->print_cr("--------------- T H R E A D ---------------"); |
duke@435 | 499 | st->cr(); |
duke@435 | 500 | } |
duke@435 | 501 | |
duke@435 | 502 | STEP(80, "(printing current thread)" ) |
duke@435 | 503 | |
duke@435 | 504 | // current thread |
duke@435 | 505 | if (_verbose) { |
duke@435 | 506 | if (_thread) { |
duke@435 | 507 | st->print("Current thread (" PTR_FORMAT "): ", _thread); |
duke@435 | 508 | _thread->print_on_error(st, buf, sizeof(buf)); |
duke@435 | 509 | st->cr(); |
duke@435 | 510 | } else { |
duke@435 | 511 | st->print_cr("Current thread is native thread"); |
duke@435 | 512 | } |
duke@435 | 513 | st->cr(); |
duke@435 | 514 | } |
duke@435 | 515 | |
duke@435 | 516 | STEP(90, "(printing siginfo)" ) |
duke@435 | 517 | |
duke@435 | 518 | // signal no, signal code, address that caused the fault |
duke@435 | 519 | if (_verbose && _siginfo) { |
duke@435 | 520 | os::print_siginfo(st, _siginfo); |
duke@435 | 521 | st->cr(); |
duke@435 | 522 | } |
duke@435 | 523 | |
duke@435 | 524 | STEP(100, "(printing registers, top of stack, instructions near pc)") |
duke@435 | 525 | |
duke@435 | 526 | // registers, top of stack, instructions near pc |
duke@435 | 527 | if (_verbose && _context) { |
duke@435 | 528 | os::print_context(st, _context); |
duke@435 | 529 | st->cr(); |
duke@435 | 530 | } |
duke@435 | 531 | |
never@2262 | 532 | STEP(105, "(printing register info)") |
never@2262 | 533 | |
never@2262 | 534 | // decode register contents if possible |
never@2262 | 535 | if (_verbose && _context && Universe::is_fully_initialized()) { |
never@2262 | 536 | os::print_register_info(st, _context); |
never@2262 | 537 | st->cr(); |
never@2262 | 538 | } |
never@2262 | 539 | |
duke@435 | 540 | STEP(110, "(printing stack bounds)" ) |
duke@435 | 541 | |
duke@435 | 542 | if (_verbose) { |
duke@435 | 543 | st->print("Stack: "); |
duke@435 | 544 | |
duke@435 | 545 | address stack_top; |
duke@435 | 546 | size_t stack_size; |
duke@435 | 547 | |
duke@435 | 548 | if (_thread) { |
duke@435 | 549 | stack_top = _thread->stack_base(); |
duke@435 | 550 | stack_size = _thread->stack_size(); |
duke@435 | 551 | } else { |
duke@435 | 552 | stack_top = os::current_stack_base(); |
duke@435 | 553 | stack_size = os::current_stack_size(); |
duke@435 | 554 | } |
duke@435 | 555 | |
duke@435 | 556 | address stack_bottom = stack_top - stack_size; |
duke@435 | 557 | st->print("[" PTR_FORMAT "," PTR_FORMAT "]", stack_bottom, stack_top); |
duke@435 | 558 | |
duke@435 | 559 | frame fr = _context ? os::fetch_frame_from_context(_context) |
duke@435 | 560 | : os::current_frame(); |
duke@435 | 561 | |
duke@435 | 562 | if (fr.sp()) { |
duke@435 | 563 | st->print(", sp=" PTR_FORMAT, fr.sp()); |
kvn@2039 | 564 | size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024); |
kvn@2039 | 565 | st->print(", free space=" SIZE_FORMAT "k", free_stack_size); |
duke@435 | 566 | } |
duke@435 | 567 | |
duke@435 | 568 | st->cr(); |
duke@435 | 569 | } |
duke@435 | 570 | |
duke@435 | 571 | STEP(120, "(printing native stack)" ) |
duke@435 | 572 | |
duke@435 | 573 | if (_verbose) { |
duke@435 | 574 | frame fr = _context ? os::fetch_frame_from_context(_context) |
duke@435 | 575 | : os::current_frame(); |
duke@435 | 576 | |
duke@435 | 577 | // see if it's a valid frame |
duke@435 | 578 | if (fr.pc()) { |
duke@435 | 579 | st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); |
duke@435 | 580 | |
zgu@2364 | 581 | |
duke@435 | 582 | int count = 0; |
duke@435 | 583 | while (count++ < StackPrintLimit) { |
duke@435 | 584 | fr.print_on_error(st, buf, sizeof(buf)); |
duke@435 | 585 | st->cr(); |
duke@435 | 586 | if (os::is_first_C_frame(&fr)) break; |
duke@435 | 587 | fr = os::get_sender_for_C_frame(&fr); |
duke@435 | 588 | } |
duke@435 | 589 | |
duke@435 | 590 | if (count > StackPrintLimit) { |
duke@435 | 591 | st->print_cr("...<more frames>..."); |
duke@435 | 592 | } |
duke@435 | 593 | |
duke@435 | 594 | st->cr(); |
duke@435 | 595 | } |
duke@435 | 596 | } |
duke@435 | 597 | |
duke@435 | 598 | STEP(130, "(printing Java stack)" ) |
duke@435 | 599 | |
duke@435 | 600 | if (_verbose && _thread && _thread->is_Java_thread()) { |
twisti@1819 | 601 | print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf)); |
duke@435 | 602 | } |
duke@435 | 603 | |
minqi@1554 | 604 | STEP(135, "(printing target Java thread stack)" ) |
minqi@1554 | 605 | |
minqi@1554 | 606 | // printing Java thread stack trace if it is involved in GC crash |
never@2262 | 607 | if (_verbose && _thread && (_thread->is_Named_thread())) { |
minqi@1554 | 608 | JavaThread* jt = ((NamedThread *)_thread)->processed_thread(); |
minqi@1554 | 609 | if (jt != NULL) { |
minqi@1554 | 610 | st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id()); |
twisti@1819 | 611 | print_stack_trace(st, jt, buf, sizeof(buf), true); |
minqi@1554 | 612 | } |
minqi@1554 | 613 | } |
minqi@1554 | 614 | |
duke@435 | 615 | STEP(140, "(printing VM operation)" ) |
duke@435 | 616 | |
duke@435 | 617 | if (_verbose && _thread && _thread->is_VM_thread()) { |
duke@435 | 618 | VMThread* t = (VMThread*)_thread; |
duke@435 | 619 | VM_Operation* op = t->vm_operation(); |
duke@435 | 620 | if (op) { |
duke@435 | 621 | op->print_on_error(st); |
duke@435 | 622 | st->cr(); |
duke@435 | 623 | st->cr(); |
duke@435 | 624 | } |
duke@435 | 625 | } |
duke@435 | 626 | |
duke@435 | 627 | STEP(150, "(printing current compile task)" ) |
duke@435 | 628 | |
duke@435 | 629 | if (_verbose && _thread && _thread->is_Compiler_thread()) { |
duke@435 | 630 | CompilerThread* t = (CompilerThread*)_thread; |
duke@435 | 631 | if (t->task()) { |
duke@435 | 632 | st->cr(); |
duke@435 | 633 | st->print_cr("Current CompileTask:"); |
duke@435 | 634 | t->task()->print_line_on_error(st, buf, sizeof(buf)); |
duke@435 | 635 | st->cr(); |
duke@435 | 636 | } |
duke@435 | 637 | } |
duke@435 | 638 | |
duke@435 | 639 | STEP(160, "(printing process)" ) |
duke@435 | 640 | |
duke@435 | 641 | if (_verbose) { |
duke@435 | 642 | st->cr(); |
duke@435 | 643 | st->print_cr("--------------- P R O C E S S ---------------"); |
duke@435 | 644 | st->cr(); |
duke@435 | 645 | } |
duke@435 | 646 | |
duke@435 | 647 | STEP(170, "(printing all threads)" ) |
duke@435 | 648 | |
duke@435 | 649 | // all threads |
duke@435 | 650 | if (_verbose && _thread) { |
duke@435 | 651 | Threads::print_on_error(st, _thread, buf, sizeof(buf)); |
duke@435 | 652 | st->cr(); |
duke@435 | 653 | } |
duke@435 | 654 | |
duke@435 | 655 | STEP(175, "(printing VM state)" ) |
duke@435 | 656 | |
duke@435 | 657 | if (_verbose) { |
duke@435 | 658 | // Safepoint state |
duke@435 | 659 | st->print("VM state:"); |
duke@435 | 660 | |
duke@435 | 661 | if (SafepointSynchronize::is_synchronizing()) st->print("synchronizing"); |
duke@435 | 662 | else if (SafepointSynchronize::is_at_safepoint()) st->print("at safepoint"); |
duke@435 | 663 | else st->print("not at safepoint"); |
duke@435 | 664 | |
duke@435 | 665 | // Also see if error occurred during initialization or shutdown |
duke@435 | 666 | if (!Universe::is_fully_initialized()) { |
duke@435 | 667 | st->print(" (not fully initialized)"); |
duke@435 | 668 | } else if (VM_Exit::vm_exited()) { |
duke@435 | 669 | st->print(" (shutting down)"); |
duke@435 | 670 | } else { |
duke@435 | 671 | st->print(" (normal execution)"); |
duke@435 | 672 | } |
duke@435 | 673 | st->cr(); |
duke@435 | 674 | st->cr(); |
duke@435 | 675 | } |
duke@435 | 676 | |
duke@435 | 677 | STEP(180, "(printing owned locks on error)" ) |
duke@435 | 678 | |
duke@435 | 679 | // mutexes/monitors that currently have an owner |
duke@435 | 680 | if (_verbose) { |
duke@435 | 681 | print_owned_locks_on_error(st); |
duke@435 | 682 | st->cr(); |
duke@435 | 683 | } |
duke@435 | 684 | |
duke@435 | 685 | STEP(190, "(printing heap information)" ) |
duke@435 | 686 | |
duke@435 | 687 | if (_verbose && Universe::is_fully_initialized()) { |
stefank@4904 | 688 | Universe::heap()->print_on_error(st); |
never@3687 | 689 | st->cr(); |
never@3687 | 690 | |
never@3687 | 691 | st->print_cr("Polling page: " INTPTR_FORMAT, os::get_polling_page()); |
never@3687 | 692 | st->cr(); |
duke@435 | 693 | } |
duke@435 | 694 | |
never@2262 | 695 | STEP(195, "(printing code cache information)" ) |
never@2262 | 696 | |
never@2262 | 697 | if (_verbose && Universe::is_fully_initialized()) { |
never@2262 | 698 | // print code cache information before vm abort |
vladidan@4438 | 699 | CodeCache::print_summary(st); |
never@2262 | 700 | st->cr(); |
never@2262 | 701 | } |
never@2262 | 702 | |
never@3499 | 703 | STEP(200, "(printing ring buffers)" ) |
never@3499 | 704 | |
never@3499 | 705 | if (_verbose) { |
never@3499 | 706 | Events::print_all(st); |
never@3499 | 707 | st->cr(); |
never@3499 | 708 | } |
never@3499 | 709 | |
never@3499 | 710 | STEP(205, "(printing dynamic libraries)" ) |
duke@435 | 711 | |
duke@435 | 712 | if (_verbose) { |
duke@435 | 713 | // dynamic libraries, or memory map |
duke@435 | 714 | os::print_dll_info(st); |
duke@435 | 715 | st->cr(); |
duke@435 | 716 | } |
duke@435 | 717 | |
duke@435 | 718 | STEP(210, "(printing VM options)" ) |
duke@435 | 719 | |
duke@435 | 720 | if (_verbose) { |
duke@435 | 721 | // VM options |
duke@435 | 722 | Arguments::print_on(st); |
duke@435 | 723 | st->cr(); |
duke@435 | 724 | } |
duke@435 | 725 | |
mgerdin@3619 | 726 | STEP(215, "(printing warning if internal testing API used)" ) |
mgerdin@3619 | 727 | |
mgerdin@3619 | 728 | if (WhiteBox::used()) { |
mgerdin@3619 | 729 | st->print_cr("Unsupported internal testing APIs have been used."); |
mgerdin@3619 | 730 | st->cr(); |
mgerdin@3619 | 731 | } |
mgerdin@3619 | 732 | |
duke@435 | 733 | STEP(220, "(printing environment variables)" ) |
duke@435 | 734 | |
duke@435 | 735 | if (_verbose) { |
duke@435 | 736 | os::print_environment_variables(st, env_list, buf, sizeof(buf)); |
duke@435 | 737 | st->cr(); |
duke@435 | 738 | } |
duke@435 | 739 | |
duke@435 | 740 | STEP(225, "(printing signal handlers)" ) |
duke@435 | 741 | |
duke@435 | 742 | if (_verbose) { |
duke@435 | 743 | os::print_signal_handlers(st, buf, sizeof(buf)); |
duke@435 | 744 | st->cr(); |
duke@435 | 745 | } |
duke@435 | 746 | |
duke@435 | 747 | STEP(230, "" ) |
duke@435 | 748 | |
duke@435 | 749 | if (_verbose) { |
duke@435 | 750 | st->cr(); |
duke@435 | 751 | st->print_cr("--------------- S Y S T E M ---------------"); |
duke@435 | 752 | st->cr(); |
duke@435 | 753 | } |
duke@435 | 754 | |
duke@435 | 755 | STEP(240, "(printing OS information)" ) |
duke@435 | 756 | |
duke@435 | 757 | if (_verbose) { |
duke@435 | 758 | os::print_os_info(st); |
duke@435 | 759 | st->cr(); |
duke@435 | 760 | } |
duke@435 | 761 | |
duke@435 | 762 | STEP(250, "(printing CPU info)" ) |
duke@435 | 763 | if (_verbose) { |
duke@435 | 764 | os::print_cpu_info(st); |
duke@435 | 765 | st->cr(); |
duke@435 | 766 | } |
duke@435 | 767 | |
duke@435 | 768 | STEP(260, "(printing memory info)" ) |
duke@435 | 769 | |
duke@435 | 770 | if (_verbose) { |
duke@435 | 771 | os::print_memory_info(st); |
duke@435 | 772 | st->cr(); |
duke@435 | 773 | } |
duke@435 | 774 | |
duke@435 | 775 | STEP(270, "(printing internal vm info)" ) |
duke@435 | 776 | |
duke@435 | 777 | if (_verbose) { |
duke@435 | 778 | st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string()); |
duke@435 | 779 | st->cr(); |
duke@435 | 780 | } |
duke@435 | 781 | |
duke@435 | 782 | STEP(280, "(printing date and time)" ) |
duke@435 | 783 | |
duke@435 | 784 | if (_verbose) { |
duke@435 | 785 | os::print_date_and_time(st); |
duke@435 | 786 | st->cr(); |
duke@435 | 787 | } |
duke@435 | 788 | |
duke@435 | 789 | END |
duke@435 | 790 | |
duke@435 | 791 | # undef BEGIN |
duke@435 | 792 | # undef STEP |
duke@435 | 793 | # undef END |
duke@435 | 794 | } |
duke@435 | 795 | |
bobv@2036 | 796 | VMError* volatile VMError::first_error = NULL; |
bobv@2036 | 797 | volatile jlong VMError::first_error_tid = -1; |
duke@435 | 798 | |
vlivanov@5027 | 799 | /** Expand a pattern into a buffer starting at pos and open a file using constructed path */ |
vlivanov@5027 | 800 | static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) { |
vlivanov@5027 | 801 | int fd = -1; |
vlivanov@5027 | 802 | if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) { |
vlivanov@5027 | 803 | fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666); |
vlivanov@5027 | 804 | } |
vlivanov@5027 | 805 | return fd; |
vlivanov@5027 | 806 | } |
vlivanov@5027 | 807 | |
vlivanov@5027 | 808 | /** |
vlivanov@5027 | 809 | * Construct file name for a log file and return it's file descriptor. |
vlivanov@5027 | 810 | * Name and location depends on pattern, default_pattern params and access |
vlivanov@5027 | 811 | * permissions. |
vlivanov@5027 | 812 | */ |
vlivanov@5027 | 813 | static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) { |
vlivanov@5027 | 814 | int fd = -1; |
vlivanov@5027 | 815 | |
vlivanov@5027 | 816 | // If possible, use specified pattern to construct log file name |
vlivanov@5027 | 817 | if (pattern != NULL) { |
vlivanov@5027 | 818 | fd = expand_and_open(pattern, buf, buflen, 0); |
vlivanov@5027 | 819 | } |
vlivanov@5027 | 820 | |
vlivanov@5027 | 821 | // Either user didn't specify, or the user's location failed, |
vlivanov@5027 | 822 | // so use the default name in the current directory |
vlivanov@5027 | 823 | if (fd == -1) { |
vlivanov@5027 | 824 | const char* cwd = os::get_current_directory(buf, buflen); |
vlivanov@5027 | 825 | if (cwd != NULL) { |
vlivanov@5027 | 826 | size_t pos = strlen(cwd); |
vlivanov@5027 | 827 | int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator()); |
vlivanov@5027 | 828 | pos += fsep_len; |
vlivanov@5027 | 829 | if (fsep_len > 0) { |
vlivanov@5027 | 830 | fd = expand_and_open(default_pattern, buf, buflen, pos); |
vlivanov@5027 | 831 | } |
vlivanov@5027 | 832 | } |
vlivanov@5027 | 833 | } |
vlivanov@5027 | 834 | |
vlivanov@5027 | 835 | // try temp directory if it exists. |
vlivanov@5027 | 836 | if (fd == -1) { |
vlivanov@5027 | 837 | const char* tmpdir = os::get_temp_directory(); |
vlivanov@5027 | 838 | if (tmpdir != NULL && strlen(tmpdir) > 0) { |
vlivanov@5027 | 839 | int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator()); |
vlivanov@5027 | 840 | if (pos > 0) { |
vlivanov@5027 | 841 | fd = expand_and_open(default_pattern, buf, buflen, pos); |
vlivanov@5027 | 842 | } |
vlivanov@5027 | 843 | } |
vlivanov@5027 | 844 | } |
vlivanov@5027 | 845 | |
vlivanov@5027 | 846 | return fd; |
vlivanov@5027 | 847 | } |
vlivanov@5027 | 848 | |
duke@435 | 849 | void VMError::report_and_die() { |
duke@435 | 850 | // Don't allocate large buffer on stack |
duke@435 | 851 | static char buffer[O_BUFLEN]; |
duke@435 | 852 | |
duke@435 | 853 | // An error could happen before tty is initialized or after it has been |
duke@435 | 854 | // destroyed. Here we use a very simple unbuffered fdStream for printing. |
duke@435 | 855 | // Only out.print_raw() and out.print_raw_cr() should be used, as other |
duke@435 | 856 | // printing methods need to allocate large buffer on stack. To format a |
duke@435 | 857 | // string, use jio_snprintf() with a static buffer or use staticBufferStream. |
duke@435 | 858 | static fdStream out(defaultStream::output_fd()); |
duke@435 | 859 | |
duke@435 | 860 | // How many errors occurred in error handler when reporting first_error. |
duke@435 | 861 | static int recursive_error_count; |
duke@435 | 862 | |
duke@435 | 863 | // We will first print a brief message to standard out (verbose = false), |
duke@435 | 864 | // then save detailed information in log file (verbose = true). |
duke@435 | 865 | static bool out_done = false; // done printing to standard out |
duke@435 | 866 | static bool log_done = false; // done saving error log |
kamg@2515 | 867 | static bool transmit_report_done = false; // done error reporting |
duke@435 | 868 | static fdStream log; // error log |
duke@435 | 869 | |
zgu@3900 | 870 | // disble NMT to avoid further exception |
zgu@3900 | 871 | MemTracker::shutdown(MemTracker::NMT_error_reporting); |
zgu@3900 | 872 | |
duke@435 | 873 | if (SuppressFatalErrorMessage) { |
duke@435 | 874 | os::abort(); |
duke@435 | 875 | } |
duke@435 | 876 | jlong mytid = os::current_thread_id(); |
duke@435 | 877 | if (first_error == NULL && |
duke@435 | 878 | Atomic::cmpxchg_ptr(this, &first_error, NULL) == NULL) { |
duke@435 | 879 | |
duke@435 | 880 | // first time |
duke@435 | 881 | first_error_tid = mytid; |
duke@435 | 882 | set_error_reported(); |
duke@435 | 883 | |
sla@2584 | 884 | if (ShowMessageBoxOnError || PauseAtExit) { |
duke@435 | 885 | show_message_box(buffer, sizeof(buffer)); |
duke@435 | 886 | |
duke@435 | 887 | // User has asked JVM to abort. Reset ShowMessageBoxOnError so the |
duke@435 | 888 | // WatcherThread can kill JVM if the error handler hangs. |
duke@435 | 889 | ShowMessageBoxOnError = false; |
duke@435 | 890 | } |
duke@435 | 891 | |
ctornqvi@2520 | 892 | // Write a minidump on Windows, check core dump limits on Linux/Solaris |
ctornqvi@2520 | 893 | os::check_or_create_dump(_siginfo, _context, buffer, sizeof(buffer)); |
ctornqvi@2520 | 894 | |
duke@435 | 895 | // reset signal handlers or exception filter; make sure recursive crashes |
duke@435 | 896 | // are handled properly. |
duke@435 | 897 | reset_signal_handlers(); |
duke@435 | 898 | |
duke@435 | 899 | } else { |
coleenp@946 | 900 | // If UseOsErrorReporting we call this for each level of the call stack |
coleenp@946 | 901 | // while searching for the exception handler. Only the first level needs |
coleenp@946 | 902 | // to be reported. |
coleenp@946 | 903 | if (UseOSErrorReporting && log_done) return; |
coleenp@946 | 904 | |
duke@435 | 905 | // This is not the first error, see if it happened in a different thread |
duke@435 | 906 | // or in the same thread during error reporting. |
duke@435 | 907 | if (first_error_tid != mytid) { |
duke@435 | 908 | jio_snprintf(buffer, sizeof(buffer), |
duke@435 | 909 | "[thread " INT64_FORMAT " also had an error]", |
duke@435 | 910 | mytid); |
duke@435 | 911 | out.print_raw_cr(buffer); |
duke@435 | 912 | |
duke@435 | 913 | // error reporting is not MT-safe, block current thread |
duke@435 | 914 | os::infinite_sleep(); |
duke@435 | 915 | |
duke@435 | 916 | } else { |
duke@435 | 917 | if (recursive_error_count++ > 30) { |
duke@435 | 918 | out.print_raw_cr("[Too many errors, abort]"); |
duke@435 | 919 | os::die(); |
duke@435 | 920 | } |
duke@435 | 921 | |
duke@435 | 922 | jio_snprintf(buffer, sizeof(buffer), |
duke@435 | 923 | "[error occurred during error reporting %s, id 0x%x]", |
duke@435 | 924 | first_error ? first_error->_current_step_info : "", |
duke@435 | 925 | _id); |
duke@435 | 926 | if (log.is_open()) { |
duke@435 | 927 | log.cr(); |
duke@435 | 928 | log.print_raw_cr(buffer); |
duke@435 | 929 | log.cr(); |
duke@435 | 930 | } else { |
duke@435 | 931 | out.cr(); |
duke@435 | 932 | out.print_raw_cr(buffer); |
duke@435 | 933 | out.cr(); |
duke@435 | 934 | } |
duke@435 | 935 | } |
duke@435 | 936 | } |
duke@435 | 937 | |
duke@435 | 938 | // print to screen |
duke@435 | 939 | if (!out_done) { |
duke@435 | 940 | first_error->_verbose = false; |
duke@435 | 941 | |
duke@435 | 942 | staticBufferStream sbs(buffer, sizeof(buffer), &out); |
duke@435 | 943 | first_error->report(&sbs); |
duke@435 | 944 | |
duke@435 | 945 | out_done = true; |
duke@435 | 946 | |
duke@435 | 947 | first_error->_current_step = 0; // reset current_step |
duke@435 | 948 | first_error->_current_step_info = ""; // reset current_step string |
duke@435 | 949 | } |
duke@435 | 950 | |
duke@435 | 951 | // print to error log file |
duke@435 | 952 | if (!log_done) { |
duke@435 | 953 | first_error->_verbose = true; |
duke@435 | 954 | |
duke@435 | 955 | // see if log file is already open |
duke@435 | 956 | if (!log.is_open()) { |
duke@435 | 957 | // open log file |
vlivanov@5027 | 958 | int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer)); |
duke@435 | 959 | if (fd != -1) { |
duke@435 | 960 | out.print_raw("# An error report file with more information is saved as:\n# "); |
duke@435 | 961 | out.print_raw_cr(buffer); |
duke@435 | 962 | os::set_error_file(buffer); |
duke@435 | 963 | |
duke@435 | 964 | log.set_fd(fd); |
duke@435 | 965 | } else { |
duke@435 | 966 | out.print_raw_cr("# Can not save log file, dump to screen.."); |
duke@435 | 967 | log.set_fd(defaultStream::output_fd()); |
kamg@2515 | 968 | /* Error reporting currently needs dumpfile. |
kamg@2515 | 969 | * Maybe implement direct streaming in the future.*/ |
kamg@2515 | 970 | transmit_report_done = true; |
duke@435 | 971 | } |
duke@435 | 972 | } |
duke@435 | 973 | |
duke@435 | 974 | staticBufferStream sbs(buffer, O_BUFLEN, &log); |
duke@435 | 975 | first_error->report(&sbs); |
duke@435 | 976 | first_error->_current_step = 0; // reset current_step |
duke@435 | 977 | first_error->_current_step_info = ""; // reset current_step string |
duke@435 | 978 | |
kamg@2515 | 979 | // Run error reporting to determine whether or not to report the crash. |
kamg@2515 | 980 | if (!transmit_report_done && should_report_bug(first_error->_id)) { |
kamg@2515 | 981 | transmit_report_done = true; |
vlivanov@5027 | 982 | FILE* hs_err = os::open(log.fd(), "r"); |
kamg@2515 | 983 | if (NULL != hs_err) { |
kamg@2515 | 984 | ErrorReporter er; |
kamg@2515 | 985 | er.call(hs_err, buffer, O_BUFLEN); |
kamg@2515 | 986 | } |
kamg@2515 | 987 | } |
kamg@2515 | 988 | |
duke@435 | 989 | if (log.fd() != defaultStream::output_fd()) { |
duke@435 | 990 | close(log.fd()); |
duke@435 | 991 | } |
duke@435 | 992 | |
duke@435 | 993 | log.set_fd(-1); |
duke@435 | 994 | log_done = true; |
duke@435 | 995 | } |
duke@435 | 996 | |
duke@435 | 997 | |
duke@435 | 998 | static bool skip_OnError = false; |
duke@435 | 999 | if (!skip_OnError && OnError && OnError[0]) { |
duke@435 | 1000 | skip_OnError = true; |
duke@435 | 1001 | |
duke@435 | 1002 | out.print_raw_cr("#"); |
duke@435 | 1003 | out.print_raw ("# -XX:OnError=\""); |
duke@435 | 1004 | out.print_raw (OnError); |
duke@435 | 1005 | out.print_raw_cr("\""); |
duke@435 | 1006 | |
duke@435 | 1007 | char* cmd; |
duke@435 | 1008 | const char* ptr = OnError; |
duke@435 | 1009 | while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ |
duke@435 | 1010 | out.print_raw ("# Executing "); |
never@3156 | 1011 | #if defined(LINUX) || defined(_ALLBSD_SOURCE) |
duke@435 | 1012 | out.print_raw ("/bin/sh -c "); |
duke@435 | 1013 | #elif defined(SOLARIS) |
duke@435 | 1014 | out.print_raw ("/usr/bin/sh -c "); |
duke@435 | 1015 | #endif |
duke@435 | 1016 | out.print_raw ("\""); |
duke@435 | 1017 | out.print_raw (cmd); |
duke@435 | 1018 | out.print_raw_cr("\" ..."); |
duke@435 | 1019 | |
duke@435 | 1020 | os::fork_and_exec(cmd); |
duke@435 | 1021 | } |
duke@435 | 1022 | |
duke@435 | 1023 | // done with OnError |
duke@435 | 1024 | OnError = NULL; |
duke@435 | 1025 | } |
duke@435 | 1026 | |
minqi@4267 | 1027 | static bool skip_replay = false; |
minqi@4267 | 1028 | if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) { |
minqi@4267 | 1029 | skip_replay = true; |
minqi@4267 | 1030 | ciEnv* env = ciEnv::current(); |
minqi@4267 | 1031 | if (env != NULL) { |
vlivanov@5027 | 1032 | int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer)); |
vlivanov@5027 | 1033 | if (fd != -1) { |
vlivanov@5027 | 1034 | FILE* replay_data_file = os::open(fd, "w"); |
vlivanov@5027 | 1035 | if (replay_data_file != NULL) { |
vlivanov@5027 | 1036 | fileStream replay_data_stream(replay_data_file, /*need_close=*/true); |
vlivanov@5027 | 1037 | env->dump_replay_data(&replay_data_stream); |
vlivanov@5027 | 1038 | out.print_raw("#\n# Compiler replay data is saved as:\n# "); |
vlivanov@5027 | 1039 | out.print_raw_cr(buffer); |
vlivanov@5027 | 1040 | } else { |
vlivanov@5027 | 1041 | out.print_raw("#\n# Can't open file to dump replay data. Error: "); |
vlivanov@5027 | 1042 | out.print_raw_cr(strerror(os::get_last_error())); |
vlivanov@5027 | 1043 | } |
vlivanov@5027 | 1044 | } |
minqi@4267 | 1045 | } |
minqi@4267 | 1046 | } |
minqi@4267 | 1047 | |
coleenp@2418 | 1048 | static bool skip_bug_url = !should_report_bug(first_error->_id); |
duke@435 | 1049 | if (!skip_bug_url) { |
duke@435 | 1050 | skip_bug_url = true; |
duke@435 | 1051 | |
duke@435 | 1052 | out.print_raw_cr("#"); |
duke@435 | 1053 | print_bug_submit_message(&out, _thread); |
duke@435 | 1054 | } |
duke@435 | 1055 | |
duke@435 | 1056 | if (!UseOSErrorReporting) { |
duke@435 | 1057 | // os::abort() will call abort hooks, try it first. |
duke@435 | 1058 | static bool skip_os_abort = false; |
duke@435 | 1059 | if (!skip_os_abort) { |
duke@435 | 1060 | skip_os_abort = true; |
coleenp@2418 | 1061 | bool dump_core = should_report_bug(first_error->_id); |
coleenp@2418 | 1062 | os::abort(dump_core); |
duke@435 | 1063 | } |
duke@435 | 1064 | |
duke@435 | 1065 | // if os::abort() doesn't abort, try os::die(); |
duke@435 | 1066 | os::die(); |
duke@435 | 1067 | } |
duke@435 | 1068 | } |
duke@435 | 1069 | |
duke@435 | 1070 | /* |
duke@435 | 1071 | * OnOutOfMemoryError scripts/commands executed while VM is a safepoint - this |
duke@435 | 1072 | * ensures utilities such as jmap can observe the process is a consistent state. |
duke@435 | 1073 | */ |
duke@435 | 1074 | class VM_ReportJavaOutOfMemory : public VM_Operation { |
duke@435 | 1075 | private: |
duke@435 | 1076 | VMError *_err; |
duke@435 | 1077 | public: |
duke@435 | 1078 | VM_ReportJavaOutOfMemory(VMError *err) { _err = err; } |
duke@435 | 1079 | VMOp_Type type() const { return VMOp_ReportJavaOutOfMemory; } |
duke@435 | 1080 | void doit(); |
duke@435 | 1081 | }; |
duke@435 | 1082 | |
duke@435 | 1083 | void VM_ReportJavaOutOfMemory::doit() { |
duke@435 | 1084 | // Don't allocate large buffer on stack |
duke@435 | 1085 | static char buffer[O_BUFLEN]; |
duke@435 | 1086 | |
duke@435 | 1087 | tty->print_cr("#"); |
duke@435 | 1088 | tty->print_cr("# java.lang.OutOfMemoryError: %s", _err->message()); |
duke@435 | 1089 | tty->print_cr("# -XX:OnOutOfMemoryError=\"%s\"", OnOutOfMemoryError); |
duke@435 | 1090 | |
duke@435 | 1091 | // make heap parsability |
duke@435 | 1092 | Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
duke@435 | 1093 | |
duke@435 | 1094 | char* cmd; |
duke@435 | 1095 | const char* ptr = OnOutOfMemoryError; |
duke@435 | 1096 | while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ |
duke@435 | 1097 | tty->print("# Executing "); |
duke@435 | 1098 | #if defined(LINUX) |
duke@435 | 1099 | tty->print ("/bin/sh -c "); |
duke@435 | 1100 | #elif defined(SOLARIS) |
duke@435 | 1101 | tty->print ("/usr/bin/sh -c "); |
duke@435 | 1102 | #endif |
duke@435 | 1103 | tty->print_cr("\"%s\"...", cmd); |
duke@435 | 1104 | |
duke@435 | 1105 | os::fork_and_exec(cmd); |
duke@435 | 1106 | } |
duke@435 | 1107 | } |
duke@435 | 1108 | |
duke@435 | 1109 | void VMError::report_java_out_of_memory() { |
duke@435 | 1110 | if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { |
duke@435 | 1111 | MutexLocker ml(Heap_lock); |
duke@435 | 1112 | VM_ReportJavaOutOfMemory op(this); |
duke@435 | 1113 | VMThread::execute(&op); |
duke@435 | 1114 | } |
duke@435 | 1115 | } |