exceptions.cpp revision 2062:3582bf76420e
1139749Simp/* 284059Swpaul * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 384059Swpaul * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 484059Swpaul * 584059Swpaul * This code is free software; you can redistribute it and/or modify it 684059Swpaul * under the terms of the GNU General Public License version 2 only, as 784059Swpaul * published by the Free Software Foundation. 884059Swpaul * 984059Swpaul * This code is distributed in the hope that it will be useful, but WITHOUT 1084059Swpaul * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1184059Swpaul * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1284059Swpaul * version 2 for more details (a copy is included in the LICENSE file that 1384059Swpaul * accompanied this code). 1484059Swpaul * 1584059Swpaul * You should have received a copy of the GNU General Public License version 1684059Swpaul * 2 along with this work; if not, write to the Free Software Foundation, 1784059Swpaul * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1884059Swpaul * 1984059Swpaul * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2084059Swpaul * or visit www.oracle.com if you need additional information or have any 2184059Swpaul * questions. 2284059Swpaul * 2384059Swpaul */ 2484059Swpaul 2584059Swpaul#include "precompiled.hpp" 2684059Swpaul#include "classfile/systemDictionary.hpp" 2784059Swpaul#include "classfile/vmSymbols.hpp" 2884059Swpaul#include "compiler/compileBroker.hpp" 2984059Swpaul#include "oops/oop.inline.hpp" 3084059Swpaul#include "runtime/init.hpp" 3184059Swpaul#include "runtime/java.hpp" 3284059Swpaul#include "runtime/javaCalls.hpp" 3384059Swpaul#include "runtime/threadCritical.hpp" 34119418Sobrien#include "utilities/events.hpp" 35119418Sobrien#include "utilities/exceptions.hpp" 36119418Sobrien#ifdef TARGET_OS_FAMILY_linux 3784059Swpaul# include "thread_linux.inline.hpp" 38245926Smarius#endif 39113038Sobrien#ifdef TARGET_OS_FAMILY_solaris 4084059Swpaul# include "thread_solaris.inline.hpp" 41245926Smarius#endif 42221344Smarius#ifdef TARGET_OS_FAMILY_windows 4384059Swpaul# include "thread_windows.inline.hpp" 4484059Swpaul#endif 4584059Swpaul 4684059Swpaul 4784059Swpaul// Implementation of ThreadShadow 4884059Swpaulvoid check_ThreadShadow() { 4984059Swpaul const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception); 5084059Swpaul const ByteSize offset2 = Thread::pending_exception_offset(); 5184059Swpaul if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly"); 5284059Swpaul} 5384059Swpaul 54137073Sdes 5584059Swpaulvoid ThreadShadow::set_pending_exception(oop exception, const char* file, int line) { 5692934Swpaul assert(exception != NULL && exception->is_oop(), "invalid exception oop"); 5784059Swpaul _pending_exception = exception; 5884059Swpaul _exception_file = file; 5984059Swpaul _exception_line = line; 6084059Swpaul} 6184059Swpaul 6284059Swpaulvoid ThreadShadow::clear_pending_exception() { 6384059Swpaul if (TraceClearedExceptions) { 6484059Swpaul if (_pending_exception != NULL) { 6584059Swpaul tty->print_cr("Thread::clear_pending_exception: cleared exception:"); 6684059Swpaul _pending_exception->print(); 6784059Swpaul } 6884059Swpaul } 69151553Sglebius _pending_exception = NULL; 70151553Sglebius _exception_file = NULL; 71151553Sglebius _exception_line = 0; 72151553Sglebius} 7384059Swpaul// Implementation of Exceptions 74118026Swpaul 7584059Swpaulbool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) { 7684059Swpaul // bootstrapping check 7784059Swpaul if (!Universe::is_fully_initialized()) { 7884059Swpaul vm_exit_during_initialization(h_exception); 7984059Swpaul ShouldNotReachHere(); 80129879Sphk } 8184059Swpaul 82162583Sscottl#ifdef ASSERT 83199668Syongari // Check for trying to throw stack overflow before initialization is complete 8484059Swpaul // to prevent infinite recursion trying to initialize stack overflow without 8584059Swpaul // adequate stack space. 8684059Swpaul // This can happen with stress testing a large value of StackShadowPages 8784059Swpaul if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) { 8884059Swpaul instanceKlass* ik = instanceKlass::cast(h_exception->klass()); 8984059Swpaul assert(ik->is_initialized(), 9084059Swpaul "need to increase min_stack_allowed calculation"); 9184059Swpaul } 9284059Swpaul#endif // ASSERT 9384059Swpaul 9484059Swpaul if (thread->is_VM_thread() 9584059Swpaul || thread->is_Compiler_thread() ) { 9684059Swpaul // We do not care what kind of exception we get for the vm-thread or a thread which 9784059Swpaul // is compiling. We just install a dummy exception object 9884059Swpaul thread->set_pending_exception(Universe::vm_exception(), file, line); 99199671Syongari return true; 10084059Swpaul } 10184059Swpaul 10284059Swpaul return false; 10384059Swpaul} 10484059Swpaul 10584059Swpaulbool Exceptions::special_exception(Thread* thread, const char* file, int line, Symbol* h_name, const char* message) { 10684059Swpaul // bootstrapping check 10784059Swpaul if (!Universe::is_fully_initialized()) { 108109514Sobrien if (h_name == NULL) { 10984059Swpaul // atleast an informative message. 11084059Swpaul vm_exit_during_initialization("Exception", message); 111169152Smarius } else { 112169152Smarius vm_exit_during_initialization(h_name, message); 113169152Smarius } 114169152Smarius ShouldNotReachHere(); 115169152Smarius } 116169152Smarius 117169152Smarius if (thread->is_VM_thread() 118119277Simp || thread->is_Compiler_thread() ) { 119119277Simp // We do not care what kind of exception we get for the vm-thread or a thread which 12084059Swpaul // is compiling. We just install a dummy exception object 12184059Swpaul thread->set_pending_exception(Universe::vm_exception(), file, line); 12284059Swpaul return true; 123211596Syongari } 124166676Sjkim return false; 12584059Swpaul} 126113506Smdodd 127113506Smdodd// This method should only be called from generated code, 12884059Swpaul// therefore the exception oop should be in the oopmap. 12984059Swpaulvoid Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) { 130151545Simp assert(exception != NULL, "exception should not be NULL"); 13184059Swpaul Handle h_exception = Handle(thread, exception); 13284059Swpaul _throw(thread, file, line, h_exception); 13384059Swpaul} 13484059Swpaul 13584059Swpaulvoid Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) { 13684059Swpaul assert(h_exception() != NULL, "exception should not be NULL"); 13784059Swpaul 13884059Swpaul // tracing (do this up front - so it works during boot strapping) 139183281Smarius if (TraceExceptions) { 140159637Sglebius ttyLocker ttyl; 141159637Sglebius ResourceMark rm; 142242625Sdim tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n" 143159637Sglebius "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT, 144159637Sglebius h_exception->print_value_string(), 14584059Swpaul message ? ": " : "", message ? message : "", 146159637Sglebius (address)h_exception(), file, line, thread); 147159637Sglebius } 148159637Sglebius // for AbortVMOnException flag 149159637Sglebius NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message)); 150159637Sglebius 151159637Sglebius // Check for special boot-strapping/vm-thread handling 152159637Sglebius if (special_exception(thread, file, line, h_exception)) return; 153159637Sglebius 154159637Sglebius assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); 155159637Sglebius 156159637Sglebius // set the pending exception 157159637Sglebius thread->set_pending_exception(h_exception(), file, line); 158159637Sglebius 159159637Sglebius // vm log 160159637Sglebius Events::log("throw_exception " INTPTR_FORMAT, (address)h_exception()); 161159637Sglebius} 162159637Sglebius 163159637Sglebius 164159637Sglebiusvoid Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_loader, Handle h_protection_domain) { 165159637Sglebius // Check for special boot-strapping/vm-thread handling 166159637Sglebius if (special_exception(thread, file, line, h_name, message)) return; 167159637Sglebius // Create and throw exception 168159637Sglebius Handle h_cause(thread, NULL); 169159637Sglebius Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); 170159637Sglebius _throw(thread, file, line, h_exception, message); 171159637Sglebius} 172214428Syongari 173214428Syongari// Throw an exception with a message and a cause 174221818Syongarivoid Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) { 175159637Sglebius // Check for special boot-strapping/vm-thread handling 176159637Sglebius if (special_exception(thread, file, line, h_name, message)) return; 177174902Sremko // Create and throw exception and init cause 178197832Sstas Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); 179253483Syongari _throw(thread, file, line, h_exception, message); 180253483Syongari} 181159637Sglebius 182159637Sglebius// This version already has a handle for name 183159637Sglebiusvoid Exceptions::_throw_msg(Thread* thread, const char* file, int line, 184159637Sglebius Symbol* name, const char* message) { 185159637Sglebius Handle h_loader(thread, NULL); 186159637Sglebius Handle h_protection_domain(thread, NULL); 187159637Sglebius Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain); 188159637Sglebius} 189159637Sglebius 190159637Sglebius// This version already has a handle for name 191159999Sglebiusvoid Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, 192159999Sglebius Symbol* name, const char* message, Handle cause) { 193159999Sglebius Handle h_loader(thread, NULL); 194159999Sglebius Handle h_protection_domain(thread, NULL); 195202268Sdelphij Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain); 196197832Sstas} 197197832Sstas 198197832Sstasvoid Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* h_name, Symbol* h_signature, JavaCallArguments *args) { 199197832Sstas // Check for special boot-strapping/vm-thread handling 200253483Syongari if (special_exception(thread, file, line, h_name, NULL)) return; 201197832Sstas // Create and throw exception 202159637Sglebius Handle h_loader(thread, NULL); 203159637Sglebius Handle h_prot(thread, NULL); 204159637Sglebius Handle h_cause(thread, NULL); 205159637Sglebius Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot); 206197832Sstas _throw(thread, file, line, exception); 207197832Sstas} 208197832Sstas 209159999Sglebius 210159999Sglebiusvoid Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) { 211197832Sstas Handle exception; 212159999Sglebius if (!THREAD->has_pending_exception()) { 213159637Sglebius klassOop k = SystemDictionary::StackOverflowError_klass(); 214159637Sglebius oop e = instanceKlass::cast(k)->allocate_instance(CHECK); 215159637Sglebius exception = Handle(THREAD, e); // fill_in_stack trace does gc 216159637Sglebius assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); 217159637Sglebius if (StackTraceInThrowable) { 218178667Sjhb java_lang_Throwable::fill_in_stack_trace(exception); 219178667Sjhb } 220197832Sstas } else { 221221445Syongari // if prior exception, throw that one instead 222243686Syongari exception = Handle(THREAD, THREAD->pending_exception()); 223258959Syongari } 224221445Syongari _throw_oop(THREAD, file, line, exception()); 225243686Syongari} 226258959Syongari 227197832Sstasvoid Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { 228221445Syongari const int max_msg_size = 1024; 229258959Syongari va_list ap; 230221445Syongari va_start(ap, format); 231258959Syongari char msg[max_msg_size]; 232258959Syongari vsnprintf(msg, max_msg_size, format, ap); 233197832Sstas msg[max_msg_size-1] = '\0'; 234197832Sstas va_end(ap); 235221445Syongari _throw_msg(thread, file, line, h_name, msg); 236221445Syongari} 237159637Sglebius 238159637Sglebius// Creates an exception oop, calls the <init> method with the given signature. 239159637Sglebius// and returns a Handle 240159637Sglebius// Initializes the cause if cause non-null 241159637SglebiusHandle Exceptions::new_exception(Thread *thread, Symbol* h_name, 242197832Sstas Symbol* signature, 243197832Sstas JavaCallArguments *args, 244197832Sstas Handle h_cause, Handle h_loader, 245197832Sstas Handle h_protection_domain) { 246159637Sglebius assert(Universe::is_fully_initialized(), 24784059Swpaul "cannot be called during initialization"); 24884059Swpaul assert(thread->is_Java_thread(), "can only be called by a Java thread"); 249159637Sglebius assert(!thread->has_pending_exception(), "already has exception"); 250159637Sglebius 251159637Sglebius Handle h_exception; 252242625Sdim 253159637Sglebius // Resolve exception klass 254159637Sglebius klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread); 255159637Sglebius instanceKlassHandle klass (thread, ik); 256159637Sglebius 257159637Sglebius if (!thread->has_pending_exception()) { 258159637Sglebius assert(klass.not_null(), "klass must exist"); 259197832Sstas // We are about to create an instance - so make sure that klass is initialized 260159637Sglebius klass->initialize(thread); 261159637Sglebius if (!thread->has_pending_exception()) { 262159637Sglebius // Allocate new exception 263199661Syongari h_exception = klass->allocate_instance_handle(thread); 264159637Sglebius if (!thread->has_pending_exception()) { 265159637Sglebius JavaValue result(T_VOID); 266159637Sglebius args->set_receiver(h_exception); 267242625Sdim // Call constructor 268159637Sglebius JavaCalls::call_special(&result, klass, 269159637Sglebius vmSymbols::object_initializer_name(), 270159637Sglebius signature, 271159637Sglebius args, 272159637Sglebius thread); 273159637Sglebius 274159637Sglebius } 275159637Sglebius } 276159637Sglebius 277159637Sglebius // Future: object initializer should take a cause argument 278159637Sglebius if (h_cause() != NULL) { 279159637Sglebius assert(h_cause->is_a(SystemDictionary::Throwable_klass()), 280159637Sglebius "exception cause is not a subclass of java/lang/Throwable"); 281159637Sglebius JavaValue result1(T_OBJECT); 282159637Sglebius JavaCallArguments args1; 283159637Sglebius args1.set_receiver(h_exception); 284159999Sglebius args1.push_oop(h_cause); 285159637Sglebius JavaCalls::call_virtual(&result1, klass, 286159637Sglebius vmSymbols::initCause_name(), 287159637Sglebius vmSymbols::throwable_throwable_signature(), 288159637Sglebius &args1, 289159637Sglebius thread); 290159637Sglebius } 291159637Sglebius } 292159637Sglebius 293159637Sglebius // Check if another exception was thrown in the process, if so rethrow that one 294159637Sglebius if (thread->has_pending_exception()) { 295159637Sglebius h_exception = Handle(thread, thread->pending_exception()); 296159637Sglebius thread->clear_pending_exception(); 297159637Sglebius } 298159637Sglebius return h_exception; 299159637Sglebius} 300159637Sglebius 301161043Sglebius// Convenience method. Calls either the <init>() or <init>(String) method when 302159637Sglebius// creating a new exception 303159637SglebiusHandle Exceptions::new_exception(Thread* thread, Symbol* h_name, 304159637Sglebius const char* message, Handle h_cause, 305159637Sglebius Handle h_loader, 306159637Sglebius Handle h_protection_domain, 307159637Sglebius ExceptionMsgToUtf8Mode to_utf8_safe) { 308159637Sglebius JavaCallArguments args; 309159637Sglebius Symbol* signature = NULL; 310167351Sjkim if (message == NULL) { 311214428Syongari signature = vmSymbols::void_method_signature(); 312214428Syongari } else { 313221818Syongari // We want to allocate storage, but we can't do that if there's 314226871Syongari // a pending exception, so we preserve any pending exception 315167351Sjkim // around the allocation. 316167351Sjkim // If we get an exception from the allocation, prefer that to 317167351Sjkim // the exception we are trying to build, or the pending exception. 318176881Sjhb // This is sort of like what PRESERVE_EXCEPTION_MARK does, except 319197832Sstas // for the preferencing and the early returns. 320197832Sstas Handle incoming_exception (thread, NULL); 321253483Syongari if (thread->has_pending_exception()) { 322197832Sstas incoming_exception = Handle(thread, thread->pending_exception()); 323197832Sstas thread->clear_pending_exception(); 324166717Sjkim } 325199661Syongari Handle msg; 326165114Sscottl if (to_utf8_safe == safe_to_utf8) { 327165114Sscottl // Make a java UTF8 string. 328178667Sjhb msg = java_lang_String::create_from_str(message, thread); 329178667Sjhb } else { 330221445Syongari // Make a java string keeping the encoding scheme of the original string. 331221445Syongari msg = java_lang_String::create_from_platform_dependent_str(message, thread); 332197832Sstas } 333197832Sstas if (thread->has_pending_exception()) { 334159637Sglebius Handle exception(thread, thread->pending_exception()); 335159637Sglebius thread->clear_pending_exception(); 336159637Sglebius return exception; 337159637Sglebius } 338159637Sglebius if (incoming_exception.not_null()) { 339159637Sglebius return incoming_exception; 340159637Sglebius } 341159637Sglebius args.push_oop(msg); 342242625Sdim signature = vmSymbols::string_void_signature(); 343159999Sglebius } 344159999Sglebius return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain); 345159999Sglebius} 346159999Sglebius 347159999Sglebius// Another convenience method that creates handles for null class loaders and 348159999Sglebius// protection domains and null causes. 349159999Sglebius// If the last parameter 'to_utf8_mode' is safe_to_utf8, 350159999Sglebius// it means we can safely ignore the encoding scheme of the message string and 351159999Sglebius// convert it directly to a java UTF8 string. Otherwise, we need to take the 352159999Sglebius// encoding scheme of the string into account. One thing we should do at some 353159999Sglebius// point is to push this flag down to class java_lang_String since other 354197832Sstas// classes may need similar functionalities. 355197832SstasHandle Exceptions::new_exception(Thread* thread, 356197832Sstas Symbol* name, 357166717Sjkim const char* message, 358165114Sscottl ExceptionMsgToUtf8Mode to_utf8_safe) { 359178667Sjhb 360221445Syongari Handle h_loader(thread, NULL); 361243686Syongari Handle h_prot(thread, NULL); 362197832Sstas Handle h_cause(thread, NULL); 363214428Syongari return Exceptions::new_exception(thread, name, message, h_cause, h_loader, 364221818Syongari h_prot, to_utf8_safe); 365226871Syongari} 366253483Syongari 367159637Sglebius// Implementation of ExceptionMark 368159637Sglebius 369159637SglebiusExceptionMark::ExceptionMark(Thread*& thread) { 370159637Sglebius thread = Thread::current(); 371167311Sjkim _thread = thread; 372167311Sjkim if (_thread->has_pending_exception()) { 373167311Sjkim oop exception = _thread->pending_exception(); 374167311Sjkim _thread->clear_pending_exception(); // Needed to avoid infinite recursion 375167311Sjkim exception->print(); 376197832Sstas fatal("ExceptionMark constructor expects no pending exceptions"); 377214428Syongari } 378243686Syongari} 379159637Sglebius 380245926Smarius 381245926SmariusExceptionMark::~ExceptionMark() { 382245926Smarius if (_thread->has_pending_exception()) { 383178667Sjhb Handle exception(_thread, _thread->pending_exception()); 384178667Sjhb _thread->clear_pending_exception(); // Needed to avoid infinite recursion 385178667Sjhb if (is_init_completed()) { 386159385Sglebius exception->print(); 387159385Sglebius fatal("ExceptionMark destructor expects no pending exceptions"); 388159385Sglebius } else { 389159385Sglebius vm_exit_during_initialization(exception); 390159385Sglebius } 391159385Sglebius } 392159385Sglebius} 393212061Syongari 394159385Sglebius// ---------------------------------------------------------------------------------------- 395212061Syongari 396212061Syongari#ifndef PRODUCT 397118026Swpaul// caller frees value_string if necessary 398232849Syongarivoid Exceptions::debug_check_abort(const char *value_string, const char* message) { 399232848Syongari if (AbortVMOnException != NULL && value_string != NULL && 400232848Syongari strstr(value_string, AbortVMOnException)) { 401178996Smarius if (AbortVMOnExceptionMessage == NULL || message == NULL || 402178667Sjhb strcmp(message, AbortVMOnExceptionMessage) == 0) { 403178667Sjhb fatal(err_msg("Saw %s, aborting", value_string)); 404178667Sjhb } 405178667Sjhb } 406178667Sjhb} 407199667Syongari 408214428Syongarivoid Exceptions::debug_check_abort(Handle exception, const char* message) { 409199668Syongari if (AbortVMOnException != NULL) { 41084059Swpaul ResourceMark rm; 411162169Sambrisko if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) { 412159385Sglebius oop msg = java_lang_Throwable::message(exception); 413213283Syongari if (msg != NULL) { 414159385Sglebius message = java_lang_String::as_utf8_string(msg); 415159385Sglebius } 416214087Syongari } 417199674Syongari debug_check_abort(instanceKlass::cast(exception()->klass())->external_name(), message); 418214428Syongari } 419161399Sglebius} 42084059Swpaul#endif 421159385Sglebius