exceptions.cpp 20.2 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
33
#include "runtime/thread.inline.hpp"
34 35 36
#include "runtime/threadCritical.hpp"
#include "utilities/events.hpp"
#include "utilities/exceptions.hpp"
D
duke 已提交
37

38
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
D
duke 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

// Implementation of ThreadShadow
void check_ThreadShadow() {
  const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception);
  const ByteSize offset2 = Thread::pending_exception_offset();
  if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly");
}


void ThreadShadow::set_pending_exception(oop exception, const char* file, int line) {
  assert(exception != NULL && exception->is_oop(), "invalid exception oop");
  _pending_exception = exception;
  _exception_file    = file;
  _exception_line    = line;
}

void ThreadShadow::clear_pending_exception() {
  if (TraceClearedExceptions) {
    if (_pending_exception != NULL) {
      tty->print_cr("Thread::clear_pending_exception: cleared exception:");
      _pending_exception->print();
    }
  }
  _pending_exception = NULL;
  _exception_file    = NULL;
  _exception_line    = 0;
}
// Implementation of Exceptions

bool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) {
  // bootstrapping check
  if (!Universe::is_fully_initialized()) {
   vm_exit_during_initialization(h_exception);
   ShouldNotReachHere();
  }

75 76 77 78 79 80
#ifdef ASSERT
  // Check for trying to throw stack overflow before initialization is complete
  // to prevent infinite recursion trying to initialize stack overflow without
  // adequate stack space.
  // This can happen with stress testing a large value of StackShadowPages
  if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) {
81
    InstanceKlass* ik = InstanceKlass::cast(h_exception->klass());
82 83 84 85 86
    assert(ik->is_initialized(),
           "need to increase min_stack_allowed calculation");
  }
#endif // ASSERT

D
duke 已提交
87
  if (thread->is_VM_thread()
88 89
      || thread->is_Compiler_thread()
      || DumpSharedSpaces ) {
D
duke 已提交
90 91
    // We do not care what kind of exception we get for the vm-thread or a thread which
    // is compiling.  We just install a dummy exception object
92 93 94
    //
    // We also cannot throw a proper exception when dumping, because we cannot run
    // Java bytecodes now. A dummy exception will suffice.
D
duke 已提交
95 96 97 98 99 100 101
    thread->set_pending_exception(Universe::vm_exception(), file, line);
    return true;
  }

  return false;
}

102
bool Exceptions::special_exception(Thread* thread, const char* file, int line, Symbol* h_name, const char* message) {
D
duke 已提交
103 104
  // bootstrapping check
  if (!Universe::is_fully_initialized()) {
105
    if (h_name == NULL) {
D
duke 已提交
106 107 108 109 110 111 112 113 114
      // atleast an informative message.
      vm_exit_during_initialization("Exception", message);
    } else {
      vm_exit_during_initialization(h_name, message);
    }
    ShouldNotReachHere();
  }

  if (thread->is_VM_thread()
115 116
      || thread->is_Compiler_thread()
      || DumpSharedSpaces ) {
D
duke 已提交
117 118
    // We do not care what kind of exception we get for the vm-thread or a thread which
    // is compiling.  We just install a dummy exception object
119 120 121
    //
    // We also cannot throw a proper exception when dumping, because we cannot run
    // Java bytecodes now. A dummy exception will suffice.
D
duke 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134 135
    thread->set_pending_exception(Universe::vm_exception(), file, line);
    return true;
  }
  return false;
}

// This method should only be called from generated code,
// therefore the exception oop should be in the oopmap.
void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) {
  assert(exception != NULL, "exception should not be NULL");
  Handle h_exception = Handle(thread, exception);
  _throw(thread, file, line, h_exception);
}

136
void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
A
anoll 已提交
137
  ResourceMark rm;
D
duke 已提交
138 139 140 141 142
  assert(h_exception() != NULL, "exception should not be NULL");

  // tracing (do this up front - so it works during boot strapping)
  if (TraceExceptions) {
    ttyLocker ttyl;
A
anoll 已提交
143
    tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
144 145 146 147
                  "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
                  h_exception->print_value_string(),
                  message ? ": " : "", message ? message : "",
                  (address)h_exception(), file, line, thread);
D
duke 已提交
148 149
  }
  // for AbortVMOnException flag
150
  NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
D
duke 已提交
151 152

  // Check for special boot-strapping/vm-thread handling
A
anoll 已提交
153 154 155
  if (special_exception(thread, file, line, h_exception)) {
    return;
  }
D
duke 已提交
156

157 158 159 160
  if (h_exception->is_a(SystemDictionary::OutOfMemoryError_klass())) {
    count_out_of_memory_exceptions(h_exception);
  }

161
  assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
D
duke 已提交
162 163 164 165 166

  // set the pending exception
  thread->set_pending_exception(h_exception(), file, line);

  // vm log
A
anoll 已提交
167 168 169
  Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
                        h_exception->print_value_string(), message ? ": " : "", message ? message : "",
                        (address)h_exception(), file, line);
D
duke 已提交
170 171 172
}


173 174
void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
                            Handle h_loader, Handle h_protection_domain) {
D
duke 已提交
175
  // Check for special boot-strapping/vm-thread handling
176
  if (special_exception(thread, file, line, name, message)) return;
D
duke 已提交
177 178
  // Create and throw exception
  Handle h_cause(thread, NULL);
179
  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
180
  _throw(thread, file, line, h_exception, message);
D
duke 已提交
181 182
}

183 184
void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
                                  Handle h_loader, Handle h_protection_domain) {
D
duke 已提交
185
  // Check for special boot-strapping/vm-thread handling
186
  if (special_exception(thread, file, line, name, message)) return;
D
duke 已提交
187
  // Create and throw exception and init cause
188
  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
189
  _throw(thread, file, line, h_exception, message);
D
duke 已提交
190 191
}

192 193 194 195 196 197 198
void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
                              Handle h_loader, Handle h_protection_domain) {
  // Check for special boot-strapping/vm-thread handling
  if (special_exception(thread, file, line, h_cause)) return;
  // Create and throw exception
  Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain);
  _throw(thread, file, line, h_exception, NULL);
D
duke 已提交
199 200
}

201
void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) {
D
duke 已提交
202
  // Check for special boot-strapping/vm-thread handling
203
  if (special_exception(thread, file, line, name, NULL)) return;
D
duke 已提交
204 205 206
  // Create and throw exception
  Handle h_loader(thread, NULL);
  Handle h_prot(thread, NULL);
207
  Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot);
D
duke 已提交
208 209 210 211
  _throw(thread, file, line, exception);
}


212 213 214 215 216 217 218 219 220 221 222 223 224
// Methods for default parameters.
// NOTE: These must be here (and not in the header file) because of include circularities.
void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) {
  _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL));
}
void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) {
  _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL));
}
void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) {
  _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL));
}


225
void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) {
D
duke 已提交
226 227
  Handle exception;
  if (!THREAD->has_pending_exception()) {
228 229
    Klass* k = SystemDictionary::StackOverflowError_klass();
    oop e = InstanceKlass::cast(k)->allocate_instance(CHECK);
D
duke 已提交
230
    exception = Handle(THREAD, e);  // fill_in_stack trace does gc
231
    assert(InstanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation");
D
duke 已提交
232
    if (StackTraceInThrowable) {
233
      java_lang_Throwable::fill_in_stack_trace(exception, method());
D
duke 已提交
234
    }
235 236
    // Increment counter for hs_err file reporting
    Atomic::inc(&Exceptions::_stack_overflow_errors);
D
duke 已提交
237 238 239 240
  } else {
    // if prior exception, throw that one instead
    exception = Handle(THREAD, THREAD->pending_exception());
  }
241
  _throw(THREAD, file, line, exception);
D
duke 已提交
242 243
}

244
void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) {
D
duke 已提交
245 246 247 248 249 250 251 252 253 254
  const int max_msg_size = 1024;
  va_list ap;
  va_start(ap, format);
  char msg[max_msg_size];
  vsnprintf(msg, max_msg_size, format, ap);
  msg[max_msg_size-1] = '\0';
  va_end(ap);
  _throw_msg(thread, file, line, h_name, msg);
}

255

D
duke 已提交
256 257
// Creates an exception oop, calls the <init> method with the given signature.
// and returns a Handle
258 259 260
Handle Exceptions::new_exception(Thread *thread, Symbol* name,
                                 Symbol* signature, JavaCallArguments *args,
                                 Handle h_loader, Handle h_protection_domain) {
D
duke 已提交
261 262 263 264 265 266 267 268
  assert(Universe::is_fully_initialized(),
    "cannot be called during initialization");
  assert(thread->is_Java_thread(), "can only be called by a Java thread");
  assert(!thread->has_pending_exception(), "already has exception");

  Handle h_exception;

  // Resolve exception klass
269
  Klass* ik = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread);
270
  instanceKlassHandle klass(thread, ik);
D
duke 已提交
271 272 273 274 275 276 277 278 279 280 281 282 283

  if (!thread->has_pending_exception()) {
    assert(klass.not_null(), "klass must exist");
    // We are about to create an instance - so make sure that klass is initialized
    klass->initialize(thread);
    if (!thread->has_pending_exception()) {
      // Allocate new exception
      h_exception = klass->allocate_instance_handle(thread);
      if (!thread->has_pending_exception()) {
        JavaValue result(T_VOID);
        args->set_receiver(h_exception);
        // Call constructor
        JavaCalls::call_special(&result, klass,
284
                                         vmSymbols::object_initializer_name(),
D
duke 已提交
285 286 287 288 289
                                         signature,
                                         args,
                                         thread);
      }
    }
290
  }
D
duke 已提交
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
  // Check if another exception was thrown in the process, if so rethrow that one
  if (thread->has_pending_exception()) {
    h_exception = Handle(thread, thread->pending_exception());
    thread->clear_pending_exception();
  }
  return h_exception;
}

// Creates an exception oop, calls the <init> method with the given signature.
// and returns a Handle
// Initializes the cause if cause non-null
Handle Exceptions::new_exception(Thread *thread, Symbol* name,
                                 Symbol* signature, JavaCallArguments *args,
                                 Handle h_cause,
                                 Handle h_loader, Handle h_protection_domain) {
  Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain);

  // Future: object initializer should take a cause argument
  if (h_cause.not_null()) {
    assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
        "exception cause is not a subclass of java/lang/Throwable");
    JavaValue result1(T_OBJECT);
    JavaCallArguments args1;
    args1.set_receiver(h_exception);
    args1.push_oop(h_cause);
    JavaCalls::call_virtual(&result1, h_exception->klass(),
                                      vmSymbols::initCause_name(),
                                      vmSymbols::throwable_throwable_signature(),
                                      &args1,
                                      thread);
D
duke 已提交
322 323 324 325 326 327 328 329 330 331
  }

  // Check if another exception was thrown in the process, if so rethrow that one
  if (thread->has_pending_exception()) {
    h_exception = Handle(thread, thread->pending_exception());
    thread->clear_pending_exception();
  }
  return h_exception;
}

332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
// Convenience method. Calls either the <init>() or <init>(Throwable) method when
// creating a new exception
Handle Exceptions::new_exception(Thread* thread, Symbol* name,
                                 Handle h_cause,
                                 Handle h_loader, Handle h_protection_domain,
                                 ExceptionMsgToUtf8Mode to_utf8_safe) {
  JavaCallArguments args;
  Symbol* signature = NULL;
  if (h_cause.is_null()) {
    signature = vmSymbols::void_method_signature();
  } else {
    signature = vmSymbols::throwable_void_signature();
    args.push_oop(h_cause);
  }
  return new_exception(thread, name, signature, &args, h_loader, h_protection_domain);
}

D
duke 已提交
349 350
// Convenience method. Calls either the <init>() or <init>(String) method when
// creating a new exception
351
Handle Exceptions::new_exception(Thread* thread, Symbol* name,
D
duke 已提交
352
                                 const char* message, Handle h_cause,
353
                                 Handle h_loader, Handle h_protection_domain,
D
duke 已提交
354 355
                                 ExceptionMsgToUtf8Mode to_utf8_safe) {
  JavaCallArguments args;
356
  Symbol* signature = NULL;
D
duke 已提交
357
  if (message == NULL) {
358
    signature = vmSymbols::void_method_signature();
D
duke 已提交
359 360 361 362 363 364 365 366
  } else {
    // We want to allocate storage, but we can't do that if there's
    // a pending exception, so we preserve any pending exception
    // around the allocation.
    // If we get an exception from the allocation, prefer that to
    // the exception we are trying to build, or the pending exception.
    // This is sort of like what PRESERVE_EXCEPTION_MARK does, except
    // for the preferencing and the early returns.
367
    Handle incoming_exception(thread, NULL);
D
duke 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
    if (thread->has_pending_exception()) {
      incoming_exception = Handle(thread, thread->pending_exception());
      thread->clear_pending_exception();
    }
    Handle msg;
    if (to_utf8_safe == safe_to_utf8) {
      // Make a java UTF8 string.
      msg = java_lang_String::create_from_str(message, thread);
    } else {
      // Make a java string keeping the encoding scheme of the original string.
      msg = java_lang_String::create_from_platform_dependent_str(message, thread);
    }
    if (thread->has_pending_exception()) {
      Handle exception(thread, thread->pending_exception());
      thread->clear_pending_exception();
      return exception;
    }
    if (incoming_exception.not_null()) {
      return incoming_exception;
    }
    args.push_oop(msg);
389
    signature = vmSymbols::string_void_signature();
D
duke 已提交
390
  }
391
  return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain);
D
duke 已提交
392 393 394 395 396 397 398 399 400 401
}

// Another convenience method that creates handles for null class loaders and
// protection domains and null causes.
// If the last parameter 'to_utf8_mode' is safe_to_utf8,
// it means we can safely ignore the encoding scheme of the message string and
// convert it directly to a java UTF8 string. Otherwise, we need to take the
// encoding scheme of the string into account. One thing we should do at some
// point is to push this flag down to class java_lang_String since other
// classes may need similar functionalities.
402
Handle Exceptions::new_exception(Thread* thread, Symbol* name,
D
duke 已提交
403 404 405 406 407 408
                                 const char* message,
                                 ExceptionMsgToUtf8Mode to_utf8_safe) {

  Handle       h_loader(thread, NULL);
  Handle       h_prot(thread, NULL);
  Handle       h_cause(thread, NULL);
409
  return Exceptions::new_exception(thread, name, message, h_cause, h_loader,
D
duke 已提交
410 411 412
                                   h_prot, to_utf8_safe);
}

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450

// Exception counting for hs_err file
volatile int Exceptions::_stack_overflow_errors = 0;
volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0;
volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0;
volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0;

void Exceptions::count_out_of_memory_exceptions(Handle exception) {
  if (exception() == Universe::out_of_memory_error_metaspace()) {
     Atomic::inc(&_out_of_memory_error_metaspace_errors);
  } else if (exception() == Universe::out_of_memory_error_class_metaspace()) {
     Atomic::inc(&_out_of_memory_error_class_metaspace_errors);
  } else {
     // everything else reported as java heap OOM
     Atomic::inc(&_out_of_memory_error_java_heap_errors);
  }
}

void print_oom_count(outputStream* st, const char *err, int count) {
  if (count > 0) {
    st->print_cr("OutOfMemoryError %s=%d", err, count);
  }
}

bool Exceptions::has_exception_counts() {
  return (_stack_overflow_errors + _out_of_memory_error_java_heap_errors +
         _out_of_memory_error_metaspace_errors + _out_of_memory_error_class_metaspace_errors) > 0;
}

void Exceptions::print_exception_counts_on_error(outputStream* st) {
  print_oom_count(st, "java_heap_errors", _out_of_memory_error_java_heap_errors);
  print_oom_count(st, "metaspace_errors", _out_of_memory_error_metaspace_errors);
  print_oom_count(st, "class_metaspace_errors", _out_of_memory_error_class_metaspace_errors);
  if (_stack_overflow_errors > 0) {
    st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors);
  }
}

D
duke 已提交
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
// Implementation of ExceptionMark

ExceptionMark::ExceptionMark(Thread*& thread) {
  thread     = Thread::current();
  _thread    = thread;
  if (_thread->has_pending_exception()) {
    oop exception = _thread->pending_exception();
    _thread->clear_pending_exception(); // Needed to avoid infinite recursion
    exception->print();
    fatal("ExceptionMark constructor expects no pending exceptions");
  }
}


ExceptionMark::~ExceptionMark() {
  if (_thread->has_pending_exception()) {
    Handle exception(_thread, _thread->pending_exception());
    _thread->clear_pending_exception(); // Needed to avoid infinite recursion
    if (is_init_completed()) {
      exception->print();
      fatal("ExceptionMark destructor expects no pending exceptions");
    } else {
      vm_exit_during_initialization(exception);
    }
  }
}

// ----------------------------------------------------------------------------------------

#ifndef PRODUCT
// caller frees value_string if necessary
482
void Exceptions::debug_check_abort(const char *value_string, const char* message) {
D
duke 已提交
483 484
  if (AbortVMOnException != NULL && value_string != NULL &&
      strstr(value_string, AbortVMOnException)) {
485 486 487 488
    if (AbortVMOnExceptionMessage == NULL || message == NULL ||
        strcmp(message, AbortVMOnExceptionMessage) == 0) {
      fatal(err_msg("Saw %s, aborting", value_string));
    }
D
duke 已提交
489 490 491
  }
}

492
void Exceptions::debug_check_abort(Handle exception, const char* message) {
D
duke 已提交
493 494
  if (AbortVMOnException != NULL) {
    ResourceMark rm;
495 496 497 498 499 500
    if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) {
      oop msg = java_lang_Throwable::message(exception);
      if (msg != NULL) {
        message = java_lang_String::as_utf8_string(msg);
      }
    }
501
    debug_check_abort(InstanceKlass::cast(exception()->klass())->external_name(), message);
D
duke 已提交
502 503 504
  }
}
#endif