1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/utilities/exceptions.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,452 @@ 1.4 +/* 1.5 + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/systemDictionary.hpp" 1.30 +#include "classfile/vmSymbols.hpp" 1.31 +#include "compiler/compileBroker.hpp" 1.32 +#include "oops/oop.inline.hpp" 1.33 +#include "runtime/init.hpp" 1.34 +#include "runtime/java.hpp" 1.35 +#include "runtime/javaCalls.hpp" 1.36 +#include "runtime/thread.inline.hpp" 1.37 +#include "runtime/threadCritical.hpp" 1.38 +#include "utilities/events.hpp" 1.39 +#include "utilities/exceptions.hpp" 1.40 + 1.41 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.42 + 1.43 +// Implementation of ThreadShadow 1.44 +void check_ThreadShadow() { 1.45 + const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception); 1.46 + const ByteSize offset2 = Thread::pending_exception_offset(); 1.47 + if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly"); 1.48 +} 1.49 + 1.50 + 1.51 +void ThreadShadow::set_pending_exception(oop exception, const char* file, int line) { 1.52 + assert(exception != NULL && exception->is_oop(), "invalid exception oop"); 1.53 + _pending_exception = exception; 1.54 + _exception_file = file; 1.55 + _exception_line = line; 1.56 +} 1.57 + 1.58 +void ThreadShadow::clear_pending_exception() { 1.59 + if (TraceClearedExceptions) { 1.60 + if (_pending_exception != NULL) { 1.61 + tty->print_cr("Thread::clear_pending_exception: cleared exception:"); 1.62 + _pending_exception->print(); 1.63 + } 1.64 + } 1.65 + _pending_exception = NULL; 1.66 + _exception_file = NULL; 1.67 + _exception_line = 0; 1.68 +} 1.69 +// Implementation of Exceptions 1.70 + 1.71 +bool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) { 1.72 + // bootstrapping check 1.73 + if (!Universe::is_fully_initialized()) { 1.74 + vm_exit_during_initialization(h_exception); 1.75 + ShouldNotReachHere(); 1.76 + } 1.77 + 1.78 +#ifdef ASSERT 1.79 + // Check for trying to throw stack overflow before initialization is complete 1.80 + // to prevent infinite recursion trying to initialize stack overflow without 1.81 + // adequate stack space. 1.82 + // This can happen with stress testing a large value of StackShadowPages 1.83 + if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) { 1.84 + InstanceKlass* ik = InstanceKlass::cast(h_exception->klass()); 1.85 + assert(ik->is_initialized(), 1.86 + "need to increase min_stack_allowed calculation"); 1.87 + } 1.88 +#endif // ASSERT 1.89 + 1.90 + if (thread->is_VM_thread() 1.91 + || thread->is_Compiler_thread() ) { 1.92 + // We do not care what kind of exception we get for the vm-thread or a thread which 1.93 + // is compiling. We just install a dummy exception object 1.94 + thread->set_pending_exception(Universe::vm_exception(), file, line); 1.95 + return true; 1.96 + } 1.97 + 1.98 + return false; 1.99 +} 1.100 + 1.101 +bool Exceptions::special_exception(Thread* thread, const char* file, int line, Symbol* h_name, const char* message) { 1.102 + // bootstrapping check 1.103 + if (!Universe::is_fully_initialized()) { 1.104 + if (h_name == NULL) { 1.105 + // atleast an informative message. 1.106 + vm_exit_during_initialization("Exception", message); 1.107 + } else { 1.108 + vm_exit_during_initialization(h_name, message); 1.109 + } 1.110 + ShouldNotReachHere(); 1.111 + } 1.112 + 1.113 + if (thread->is_VM_thread() 1.114 + || thread->is_Compiler_thread() ) { 1.115 + // We do not care what kind of exception we get for the vm-thread or a thread which 1.116 + // is compiling. We just install a dummy exception object 1.117 + thread->set_pending_exception(Universe::vm_exception(), file, line); 1.118 + return true; 1.119 + } 1.120 + return false; 1.121 +} 1.122 + 1.123 +// This method should only be called from generated code, 1.124 +// therefore the exception oop should be in the oopmap. 1.125 +void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) { 1.126 + assert(exception != NULL, "exception should not be NULL"); 1.127 + Handle h_exception = Handle(thread, exception); 1.128 + _throw(thread, file, line, h_exception); 1.129 +} 1.130 + 1.131 +void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) { 1.132 + ResourceMark rm; 1.133 + assert(h_exception() != NULL, "exception should not be NULL"); 1.134 + 1.135 + // tracing (do this up front - so it works during boot strapping) 1.136 + if (TraceExceptions) { 1.137 + ttyLocker ttyl; 1.138 + tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n" 1.139 + "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT, 1.140 + h_exception->print_value_string(), 1.141 + message ? ": " : "", message ? message : "", 1.142 + (address)h_exception(), file, line, thread); 1.143 + } 1.144 + // for AbortVMOnException flag 1.145 + NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message)); 1.146 + 1.147 + // Check for special boot-strapping/vm-thread handling 1.148 + if (special_exception(thread, file, line, h_exception)) { 1.149 + return; 1.150 + } 1.151 + 1.152 + assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); 1.153 + 1.154 + // set the pending exception 1.155 + thread->set_pending_exception(h_exception(), file, line); 1.156 + 1.157 + // vm log 1.158 + Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]", 1.159 + h_exception->print_value_string(), message ? ": " : "", message ? message : "", 1.160 + (address)h_exception(), file, line); 1.161 +} 1.162 + 1.163 + 1.164 +void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message, 1.165 + Handle h_loader, Handle h_protection_domain) { 1.166 + // Check for special boot-strapping/vm-thread handling 1.167 + if (special_exception(thread, file, line, name, message)) return; 1.168 + // Create and throw exception 1.169 + Handle h_cause(thread, NULL); 1.170 + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); 1.171 + _throw(thread, file, line, h_exception, message); 1.172 +} 1.173 + 1.174 +void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, 1.175 + Handle h_loader, Handle h_protection_domain) { 1.176 + // Check for special boot-strapping/vm-thread handling 1.177 + if (special_exception(thread, file, line, name, message)) return; 1.178 + // Create and throw exception and init cause 1.179 + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); 1.180 + _throw(thread, file, line, h_exception, message); 1.181 +} 1.182 + 1.183 +void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause, 1.184 + Handle h_loader, Handle h_protection_domain) { 1.185 + // Check for special boot-strapping/vm-thread handling 1.186 + if (special_exception(thread, file, line, h_cause)) return; 1.187 + // Create and throw exception 1.188 + Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain); 1.189 + _throw(thread, file, line, h_exception, NULL); 1.190 +} 1.191 + 1.192 +void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) { 1.193 + // Check for special boot-strapping/vm-thread handling 1.194 + if (special_exception(thread, file, line, name, NULL)) return; 1.195 + // Create and throw exception 1.196 + Handle h_loader(thread, NULL); 1.197 + Handle h_prot(thread, NULL); 1.198 + Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot); 1.199 + _throw(thread, file, line, exception); 1.200 +} 1.201 + 1.202 + 1.203 +// Methods for default parameters. 1.204 +// NOTE: These must be here (and not in the header file) because of include circularities. 1.205 +void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) { 1.206 + _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL)); 1.207 +} 1.208 +void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) { 1.209 + _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL)); 1.210 +} 1.211 +void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) { 1.212 + _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL)); 1.213 +} 1.214 + 1.215 + 1.216 +void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) { 1.217 + Handle exception; 1.218 + if (!THREAD->has_pending_exception()) { 1.219 + Klass* k = SystemDictionary::StackOverflowError_klass(); 1.220 + oop e = InstanceKlass::cast(k)->allocate_instance(CHECK); 1.221 + exception = Handle(THREAD, e); // fill_in_stack trace does gc 1.222 + assert(InstanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); 1.223 + if (StackTraceInThrowable) { 1.224 + java_lang_Throwable::fill_in_stack_trace(exception, method()); 1.225 + } 1.226 + } else { 1.227 + // if prior exception, throw that one instead 1.228 + exception = Handle(THREAD, THREAD->pending_exception()); 1.229 + } 1.230 + _throw(THREAD, file, line, exception); 1.231 +} 1.232 + 1.233 +void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { 1.234 + const int max_msg_size = 1024; 1.235 + va_list ap; 1.236 + va_start(ap, format); 1.237 + char msg[max_msg_size]; 1.238 + vsnprintf(msg, max_msg_size, format, ap); 1.239 + msg[max_msg_size-1] = '\0'; 1.240 + va_end(ap); 1.241 + _throw_msg(thread, file, line, h_name, msg); 1.242 +} 1.243 + 1.244 + 1.245 +// Creates an exception oop, calls the <init> method with the given signature. 1.246 +// and returns a Handle 1.247 +Handle Exceptions::new_exception(Thread *thread, Symbol* name, 1.248 + Symbol* signature, JavaCallArguments *args, 1.249 + Handle h_loader, Handle h_protection_domain) { 1.250 + assert(Universe::is_fully_initialized(), 1.251 + "cannot be called during initialization"); 1.252 + assert(thread->is_Java_thread(), "can only be called by a Java thread"); 1.253 + assert(!thread->has_pending_exception(), "already has exception"); 1.254 + 1.255 + Handle h_exception; 1.256 + 1.257 + // Resolve exception klass 1.258 + Klass* ik = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread); 1.259 + instanceKlassHandle klass(thread, ik); 1.260 + 1.261 + if (!thread->has_pending_exception()) { 1.262 + assert(klass.not_null(), "klass must exist"); 1.263 + // We are about to create an instance - so make sure that klass is initialized 1.264 + klass->initialize(thread); 1.265 + if (!thread->has_pending_exception()) { 1.266 + // Allocate new exception 1.267 + h_exception = klass->allocate_instance_handle(thread); 1.268 + if (!thread->has_pending_exception()) { 1.269 + JavaValue result(T_VOID); 1.270 + args->set_receiver(h_exception); 1.271 + // Call constructor 1.272 + JavaCalls::call_special(&result, klass, 1.273 + vmSymbols::object_initializer_name(), 1.274 + signature, 1.275 + args, 1.276 + thread); 1.277 + } 1.278 + } 1.279 + } 1.280 + 1.281 + // Check if another exception was thrown in the process, if so rethrow that one 1.282 + if (thread->has_pending_exception()) { 1.283 + h_exception = Handle(thread, thread->pending_exception()); 1.284 + thread->clear_pending_exception(); 1.285 + } 1.286 + return h_exception; 1.287 +} 1.288 + 1.289 +// Creates an exception oop, calls the <init> method with the given signature. 1.290 +// and returns a Handle 1.291 +// Initializes the cause if cause non-null 1.292 +Handle Exceptions::new_exception(Thread *thread, Symbol* name, 1.293 + Symbol* signature, JavaCallArguments *args, 1.294 + Handle h_cause, 1.295 + Handle h_loader, Handle h_protection_domain) { 1.296 + Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain); 1.297 + 1.298 + // Future: object initializer should take a cause argument 1.299 + if (h_cause.not_null()) { 1.300 + assert(h_cause->is_a(SystemDictionary::Throwable_klass()), 1.301 + "exception cause is not a subclass of java/lang/Throwable"); 1.302 + JavaValue result1(T_OBJECT); 1.303 + JavaCallArguments args1; 1.304 + args1.set_receiver(h_exception); 1.305 + args1.push_oop(h_cause); 1.306 + JavaCalls::call_virtual(&result1, h_exception->klass(), 1.307 + vmSymbols::initCause_name(), 1.308 + vmSymbols::throwable_throwable_signature(), 1.309 + &args1, 1.310 + thread); 1.311 + } 1.312 + 1.313 + // Check if another exception was thrown in the process, if so rethrow that one 1.314 + if (thread->has_pending_exception()) { 1.315 + h_exception = Handle(thread, thread->pending_exception()); 1.316 + thread->clear_pending_exception(); 1.317 + } 1.318 + return h_exception; 1.319 +} 1.320 + 1.321 +// Convenience method. Calls either the <init>() or <init>(Throwable) method when 1.322 +// creating a new exception 1.323 +Handle Exceptions::new_exception(Thread* thread, Symbol* name, 1.324 + Handle h_cause, 1.325 + Handle h_loader, Handle h_protection_domain, 1.326 + ExceptionMsgToUtf8Mode to_utf8_safe) { 1.327 + JavaCallArguments args; 1.328 + Symbol* signature = NULL; 1.329 + if (h_cause.is_null()) { 1.330 + signature = vmSymbols::void_method_signature(); 1.331 + } else { 1.332 + signature = vmSymbols::throwable_void_signature(); 1.333 + args.push_oop(h_cause); 1.334 + } 1.335 + return new_exception(thread, name, signature, &args, h_loader, h_protection_domain); 1.336 +} 1.337 + 1.338 +// Convenience method. Calls either the <init>() or <init>(String) method when 1.339 +// creating a new exception 1.340 +Handle Exceptions::new_exception(Thread* thread, Symbol* name, 1.341 + const char* message, Handle h_cause, 1.342 + Handle h_loader, Handle h_protection_domain, 1.343 + ExceptionMsgToUtf8Mode to_utf8_safe) { 1.344 + JavaCallArguments args; 1.345 + Symbol* signature = NULL; 1.346 + if (message == NULL) { 1.347 + signature = vmSymbols::void_method_signature(); 1.348 + } else { 1.349 + // We want to allocate storage, but we can't do that if there's 1.350 + // a pending exception, so we preserve any pending exception 1.351 + // around the allocation. 1.352 + // If we get an exception from the allocation, prefer that to 1.353 + // the exception we are trying to build, or the pending exception. 1.354 + // This is sort of like what PRESERVE_EXCEPTION_MARK does, except 1.355 + // for the preferencing and the early returns. 1.356 + Handle incoming_exception(thread, NULL); 1.357 + if (thread->has_pending_exception()) { 1.358 + incoming_exception = Handle(thread, thread->pending_exception()); 1.359 + thread->clear_pending_exception(); 1.360 + } 1.361 + Handle msg; 1.362 + if (to_utf8_safe == safe_to_utf8) { 1.363 + // Make a java UTF8 string. 1.364 + msg = java_lang_String::create_from_str(message, thread); 1.365 + } else { 1.366 + // Make a java string keeping the encoding scheme of the original string. 1.367 + msg = java_lang_String::create_from_platform_dependent_str(message, thread); 1.368 + } 1.369 + if (thread->has_pending_exception()) { 1.370 + Handle exception(thread, thread->pending_exception()); 1.371 + thread->clear_pending_exception(); 1.372 + return exception; 1.373 + } 1.374 + if (incoming_exception.not_null()) { 1.375 + return incoming_exception; 1.376 + } 1.377 + args.push_oop(msg); 1.378 + signature = vmSymbols::string_void_signature(); 1.379 + } 1.380 + return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain); 1.381 +} 1.382 + 1.383 +// Another convenience method that creates handles for null class loaders and 1.384 +// protection domains and null causes. 1.385 +// If the last parameter 'to_utf8_mode' is safe_to_utf8, 1.386 +// it means we can safely ignore the encoding scheme of the message string and 1.387 +// convert it directly to a java UTF8 string. Otherwise, we need to take the 1.388 +// encoding scheme of the string into account. One thing we should do at some 1.389 +// point is to push this flag down to class java_lang_String since other 1.390 +// classes may need similar functionalities. 1.391 +Handle Exceptions::new_exception(Thread* thread, Symbol* name, 1.392 + const char* message, 1.393 + ExceptionMsgToUtf8Mode to_utf8_safe) { 1.394 + 1.395 + Handle h_loader(thread, NULL); 1.396 + Handle h_prot(thread, NULL); 1.397 + Handle h_cause(thread, NULL); 1.398 + return Exceptions::new_exception(thread, name, message, h_cause, h_loader, 1.399 + h_prot, to_utf8_safe); 1.400 +} 1.401 + 1.402 +// Implementation of ExceptionMark 1.403 + 1.404 +ExceptionMark::ExceptionMark(Thread*& thread) { 1.405 + thread = Thread::current(); 1.406 + _thread = thread; 1.407 + if (_thread->has_pending_exception()) { 1.408 + oop exception = _thread->pending_exception(); 1.409 + _thread->clear_pending_exception(); // Needed to avoid infinite recursion 1.410 + exception->print(); 1.411 + fatal("ExceptionMark constructor expects no pending exceptions"); 1.412 + } 1.413 +} 1.414 + 1.415 + 1.416 +ExceptionMark::~ExceptionMark() { 1.417 + if (_thread->has_pending_exception()) { 1.418 + Handle exception(_thread, _thread->pending_exception()); 1.419 + _thread->clear_pending_exception(); // Needed to avoid infinite recursion 1.420 + if (is_init_completed()) { 1.421 + exception->print(); 1.422 + fatal("ExceptionMark destructor expects no pending exceptions"); 1.423 + } else { 1.424 + vm_exit_during_initialization(exception); 1.425 + } 1.426 + } 1.427 +} 1.428 + 1.429 +// ---------------------------------------------------------------------------------------- 1.430 + 1.431 +#ifndef PRODUCT 1.432 +// caller frees value_string if necessary 1.433 +void Exceptions::debug_check_abort(const char *value_string, const char* message) { 1.434 + if (AbortVMOnException != NULL && value_string != NULL && 1.435 + strstr(value_string, AbortVMOnException)) { 1.436 + if (AbortVMOnExceptionMessage == NULL || message == NULL || 1.437 + strcmp(message, AbortVMOnExceptionMessage) == 0) { 1.438 + fatal(err_msg("Saw %s, aborting", value_string)); 1.439 + } 1.440 + } 1.441 +} 1.442 + 1.443 +void Exceptions::debug_check_abort(Handle exception, const char* message) { 1.444 + if (AbortVMOnException != NULL) { 1.445 + ResourceMark rm; 1.446 + if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) { 1.447 + oop msg = java_lang_Throwable::message(exception); 1.448 + if (msg != NULL) { 1.449 + message = java_lang_String::as_utf8_string(msg); 1.450 + } 1.451 + } 1.452 + debug_check_abort(InstanceKlass::cast(exception()->klass())->external_name(), message); 1.453 + } 1.454 +} 1.455 +#endif