src/hotspot/share/utilities/exceptions.cpp
changeset 47216 71c04702a3d5
parent 47103 a993ec29ec75
child 47689 54b78d6243c5
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "classfile/systemDictionary.hpp"
       
    27 #include "classfile/vmSymbols.hpp"
       
    28 #include "compiler/compileBroker.hpp"
       
    29 #include "logging/log.hpp"
       
    30 #include "logging/logStream.hpp"
       
    31 #include "memory/resourceArea.hpp"
       
    32 #include "oops/oop.inline.hpp"
       
    33 #include "runtime/init.hpp"
       
    34 #include "runtime/java.hpp"
       
    35 #include "runtime/javaCalls.hpp"
       
    36 #include "runtime/thread.inline.hpp"
       
    37 #include "runtime/threadCritical.hpp"
       
    38 #include "utilities/events.hpp"
       
    39 #include "utilities/exceptions.hpp"
       
    40 
       
    41 // Implementation of ThreadShadow
       
    42 void check_ThreadShadow() {
       
    43   const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception);
       
    44   const ByteSize offset2 = Thread::pending_exception_offset();
       
    45   if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly");
       
    46 }
       
    47 
       
    48 
       
    49 void ThreadShadow::set_pending_exception(oop exception, const char* file, int line) {
       
    50   assert(exception != NULL && oopDesc::is_oop(exception), "invalid exception oop");
       
    51   _pending_exception = exception;
       
    52   _exception_file    = file;
       
    53   _exception_line    = line;
       
    54 }
       
    55 
       
    56 void ThreadShadow::clear_pending_exception() {
       
    57   LogTarget(Debug, exceptions) lt;
       
    58   if (_pending_exception != NULL && lt.is_enabled()) {
       
    59     ResourceMark rm;
       
    60     LogStream ls(lt);
       
    61     ls.print("Thread::clear_pending_exception: cleared exception:");
       
    62     _pending_exception->print_on(&ls);
       
    63   }
       
    64   _pending_exception = NULL;
       
    65   _exception_file    = NULL;
       
    66   _exception_line    = 0;
       
    67 }
       
    68 // Implementation of Exceptions
       
    69 
       
    70 bool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) {
       
    71   // bootstrapping check
       
    72   if (!Universe::is_fully_initialized()) {
       
    73    vm_exit_during_initialization(h_exception);
       
    74    ShouldNotReachHere();
       
    75   }
       
    76 
       
    77 #ifdef ASSERT
       
    78   // Check for trying to throw stack overflow before initialization is complete
       
    79   // to prevent infinite recursion trying to initialize stack overflow without
       
    80   // adequate stack space.
       
    81   // This can happen with stress testing a large value of StackShadowPages
       
    82   if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) {
       
    83     InstanceKlass* ik = InstanceKlass::cast(h_exception->klass());
       
    84     assert(ik->is_initialized(),
       
    85            "need to increase java_thread_min_stack_allowed calculation");
       
    86   }
       
    87 #endif // ASSERT
       
    88 
       
    89   if (thread->is_VM_thread()
       
    90       || !thread->can_call_java()) {
       
    91     // We do not care what kind of exception we get for the vm-thread or a thread which
       
    92     // is compiling.  We just install a dummy exception object
       
    93     thread->set_pending_exception(Universe::vm_exception(), file, line);
       
    94     return true;
       
    95   }
       
    96 
       
    97   return false;
       
    98 }
       
    99 
       
   100 bool Exceptions::special_exception(Thread* thread, const char* file, int line, Symbol* h_name, const char* message) {
       
   101   // bootstrapping check
       
   102   if (!Universe::is_fully_initialized()) {
       
   103     if (h_name == NULL) {
       
   104       // atleast an informative message.
       
   105       vm_exit_during_initialization("Exception", message);
       
   106     } else {
       
   107       vm_exit_during_initialization(h_name, message);
       
   108     }
       
   109     ShouldNotReachHere();
       
   110   }
       
   111 
       
   112   if (thread->is_VM_thread()
       
   113       || !thread->can_call_java()) {
       
   114     // We do not care what kind of exception we get for the vm-thread or a thread which
       
   115     // is compiling.  We just install a dummy exception object
       
   116     thread->set_pending_exception(Universe::vm_exception(), file, line);
       
   117     return true;
       
   118   }
       
   119   return false;
       
   120 }
       
   121 
       
   122 // This method should only be called from generated code,
       
   123 // therefore the exception oop should be in the oopmap.
       
   124 void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) {
       
   125   assert(exception != NULL, "exception should not be NULL");
       
   126   Handle h_exception(thread, exception);
       
   127   _throw(thread, file, line, h_exception);
       
   128 }
       
   129 
       
   130 void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
       
   131   ResourceMark rm;
       
   132   assert(h_exception() != NULL, "exception should not be NULL");
       
   133 
       
   134   // tracing (do this up front - so it works during boot strapping)
       
   135   log_info(exceptions)("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
       
   136                        "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
       
   137                        h_exception->print_value_string(),
       
   138                        message ? ": " : "", message ? message : "",
       
   139                        p2i(h_exception()), file, line, p2i(thread));
       
   140   // for AbortVMOnException flag
       
   141   Exceptions::debug_check_abort(h_exception, message);
       
   142 
       
   143   // Check for special boot-strapping/vm-thread handling
       
   144   if (special_exception(thread, file, line, h_exception)) {
       
   145     return;
       
   146   }
       
   147 
       
   148   if (h_exception->is_a(SystemDictionary::OutOfMemoryError_klass())) {
       
   149     count_out_of_memory_exceptions(h_exception);
       
   150   }
       
   151 
       
   152   assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
       
   153 
       
   154   // set the pending exception
       
   155   thread->set_pending_exception(h_exception(), file, line);
       
   156 
       
   157   // vm log
       
   158   if (LogEvents){
       
   159     Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
       
   160                           h_exception->print_value_string(), message ? ": " : "", message ? message : "",
       
   161                           p2i(h_exception()), file, line);
       
   162   }
       
   163 }
       
   164 
       
   165 
       
   166 void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
       
   167                             Handle h_loader, Handle h_protection_domain) {
       
   168   // Check for special boot-strapping/vm-thread handling
       
   169   if (special_exception(thread, file, line, name, message)) return;
       
   170   // Create and throw exception
       
   171   Handle h_cause(thread, NULL);
       
   172   Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
       
   173   _throw(thread, file, line, h_exception, message);
       
   174 }
       
   175 
       
   176 void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
       
   177                                   Handle h_loader, Handle h_protection_domain) {
       
   178   // Check for special boot-strapping/vm-thread handling
       
   179   if (special_exception(thread, file, line, name, message)) return;
       
   180   // Create and throw exception and init cause
       
   181   Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
       
   182   _throw(thread, file, line, h_exception, message);
       
   183 }
       
   184 
       
   185 void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
       
   186                               Handle h_loader, Handle h_protection_domain) {
       
   187   // Check for special boot-strapping/vm-thread handling
       
   188   if (special_exception(thread, file, line, h_cause)) return;
       
   189   // Create and throw exception
       
   190   Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain);
       
   191   _throw(thread, file, line, h_exception, NULL);
       
   192 }
       
   193 
       
   194 void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) {
       
   195   // Check for special boot-strapping/vm-thread handling
       
   196   if (special_exception(thread, file, line, name, NULL)) return;
       
   197   // Create and throw exception
       
   198   Handle h_loader(thread, NULL);
       
   199   Handle h_prot(thread, NULL);
       
   200   Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot);
       
   201   _throw(thread, file, line, exception);
       
   202 }
       
   203 
       
   204 
       
   205 // Methods for default parameters.
       
   206 // NOTE: These must be here (and not in the header file) because of include circularities.
       
   207 void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) {
       
   208   _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL));
       
   209 }
       
   210 void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) {
       
   211   _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL));
       
   212 }
       
   213 void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) {
       
   214   _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL));
       
   215 }
       
   216 
       
   217 
       
   218 void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, const methodHandle& method) {
       
   219   Handle exception;
       
   220   if (!THREAD->has_pending_exception()) {
       
   221     Klass* k = SystemDictionary::StackOverflowError_klass();
       
   222     oop e = InstanceKlass::cast(k)->allocate_instance(CHECK);
       
   223     exception = Handle(THREAD, e);  // fill_in_stack trace does gc
       
   224     assert(InstanceKlass::cast(k)->is_initialized(), "need to increase java_thread_min_stack_allowed calculation");
       
   225     if (StackTraceInThrowable) {
       
   226       java_lang_Throwable::fill_in_stack_trace(exception, method());
       
   227     }
       
   228     // Increment counter for hs_err file reporting
       
   229     Atomic::inc(&Exceptions::_stack_overflow_errors);
       
   230   } else {
       
   231     // if prior exception, throw that one instead
       
   232     exception = Handle(THREAD, THREAD->pending_exception());
       
   233   }
       
   234   _throw(THREAD, file, line, exception);
       
   235 }
       
   236 
       
   237 void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) {
       
   238   const int max_msg_size = 1024;
       
   239   va_list ap;
       
   240   va_start(ap, format);
       
   241   char msg[max_msg_size];
       
   242   vsnprintf(msg, max_msg_size, format, ap);
       
   243   msg[max_msg_size-1] = '\0';
       
   244   va_end(ap);
       
   245   _throw_msg(thread, file, line, h_name, msg);
       
   246 }
       
   247 
       
   248 
       
   249 // Creates an exception oop, calls the <init> method with the given signature.
       
   250 // and returns a Handle
       
   251 Handle Exceptions::new_exception(Thread *thread, Symbol* name,
       
   252                                  Symbol* signature, JavaCallArguments *args,
       
   253                                  Handle h_loader, Handle h_protection_domain) {
       
   254   assert(Universe::is_fully_initialized(),
       
   255     "cannot be called during initialization");
       
   256   assert(thread->is_Java_thread(), "can only be called by a Java thread");
       
   257   assert(!thread->has_pending_exception(), "already has exception");
       
   258 
       
   259   Handle h_exception;
       
   260 
       
   261   // Resolve exception klass
       
   262   InstanceKlass* klass = InstanceKlass::cast(SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread));
       
   263 
       
   264   if (!thread->has_pending_exception()) {
       
   265     assert(klass != NULL, "klass must exist");
       
   266     // We are about to create an instance - so make sure that klass is initialized
       
   267     klass->initialize(thread);
       
   268     if (!thread->has_pending_exception()) {
       
   269       // Allocate new exception
       
   270       h_exception = klass->allocate_instance_handle(thread);
       
   271       if (!thread->has_pending_exception()) {
       
   272         JavaValue result(T_VOID);
       
   273         args->set_receiver(h_exception);
       
   274         // Call constructor
       
   275         JavaCalls::call_special(&result, klass,
       
   276                                          vmSymbols::object_initializer_name(),
       
   277                                          signature,
       
   278                                          args,
       
   279                                          thread);
       
   280       }
       
   281     }
       
   282   }
       
   283 
       
   284   // Check if another exception was thrown in the process, if so rethrow that one
       
   285   if (thread->has_pending_exception()) {
       
   286     h_exception = Handle(thread, thread->pending_exception());
       
   287     thread->clear_pending_exception();
       
   288   }
       
   289   return h_exception;
       
   290 }
       
   291 
       
   292 // Creates an exception oop, calls the <init> method with the given signature.
       
   293 // and returns a Handle
       
   294 // Initializes the cause if cause non-null
       
   295 Handle Exceptions::new_exception(Thread *thread, Symbol* name,
       
   296                                  Symbol* signature, JavaCallArguments *args,
       
   297                                  Handle h_cause,
       
   298                                  Handle h_loader, Handle h_protection_domain) {
       
   299   Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain);
       
   300 
       
   301   // Future: object initializer should take a cause argument
       
   302   if (h_cause.not_null()) {
       
   303     assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
       
   304         "exception cause is not a subclass of java/lang/Throwable");
       
   305     JavaValue result1(T_OBJECT);
       
   306     JavaCallArguments args1;
       
   307     args1.set_receiver(h_exception);
       
   308     args1.push_oop(h_cause);
       
   309     JavaCalls::call_virtual(&result1, h_exception->klass(),
       
   310                                       vmSymbols::initCause_name(),
       
   311                                       vmSymbols::throwable_throwable_signature(),
       
   312                                       &args1,
       
   313                                       thread);
       
   314   }
       
   315 
       
   316   // Check if another exception was thrown in the process, if so rethrow that one
       
   317   if (thread->has_pending_exception()) {
       
   318     h_exception = Handle(thread, thread->pending_exception());
       
   319     thread->clear_pending_exception();
       
   320   }
       
   321   return h_exception;
       
   322 }
       
   323 
       
   324 // Convenience method. Calls either the <init>() or <init>(Throwable) method when
       
   325 // creating a new exception
       
   326 Handle Exceptions::new_exception(Thread* thread, Symbol* name,
       
   327                                  Handle h_cause,
       
   328                                  Handle h_loader, Handle h_protection_domain,
       
   329                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
       
   330   JavaCallArguments args;
       
   331   Symbol* signature = NULL;
       
   332   if (h_cause.is_null()) {
       
   333     signature = vmSymbols::void_method_signature();
       
   334   } else {
       
   335     signature = vmSymbols::throwable_void_signature();
       
   336     args.push_oop(h_cause);
       
   337   }
       
   338   return new_exception(thread, name, signature, &args, h_loader, h_protection_domain);
       
   339 }
       
   340 
       
   341 // Convenience method. Calls either the <init>() or <init>(String) method when
       
   342 // creating a new exception
       
   343 Handle Exceptions::new_exception(Thread* thread, Symbol* name,
       
   344                                  const char* message, Handle h_cause,
       
   345                                  Handle h_loader, Handle h_protection_domain,
       
   346                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
       
   347   JavaCallArguments args;
       
   348   Symbol* signature = NULL;
       
   349   if (message == NULL) {
       
   350     signature = vmSymbols::void_method_signature();
       
   351   } else {
       
   352     // We want to allocate storage, but we can't do that if there's
       
   353     // a pending exception, so we preserve any pending exception
       
   354     // around the allocation.
       
   355     // If we get an exception from the allocation, prefer that to
       
   356     // the exception we are trying to build, or the pending exception.
       
   357     // This is sort of like what PRESERVE_EXCEPTION_MARK does, except
       
   358     // for the preferencing and the early returns.
       
   359     Handle incoming_exception(thread, NULL);
       
   360     if (thread->has_pending_exception()) {
       
   361       incoming_exception = Handle(thread, thread->pending_exception());
       
   362       thread->clear_pending_exception();
       
   363     }
       
   364     Handle msg;
       
   365     if (to_utf8_safe == safe_to_utf8) {
       
   366       // Make a java UTF8 string.
       
   367       msg = java_lang_String::create_from_str(message, thread);
       
   368     } else {
       
   369       // Make a java string keeping the encoding scheme of the original string.
       
   370       msg = java_lang_String::create_from_platform_dependent_str(message, thread);
       
   371     }
       
   372     if (thread->has_pending_exception()) {
       
   373       Handle exception(thread, thread->pending_exception());
       
   374       thread->clear_pending_exception();
       
   375       return exception;
       
   376     }
       
   377     if (incoming_exception.not_null()) {
       
   378       return incoming_exception;
       
   379     }
       
   380     args.push_oop(msg);
       
   381     signature = vmSymbols::string_void_signature();
       
   382   }
       
   383   return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain);
       
   384 }
       
   385 
       
   386 // Another convenience method that creates handles for null class loaders and
       
   387 // protection domains and null causes.
       
   388 // If the last parameter 'to_utf8_mode' is safe_to_utf8,
       
   389 // it means we can safely ignore the encoding scheme of the message string and
       
   390 // convert it directly to a java UTF8 string. Otherwise, we need to take the
       
   391 // encoding scheme of the string into account. One thing we should do at some
       
   392 // point is to push this flag down to class java_lang_String since other
       
   393 // classes may need similar functionalities.
       
   394 Handle Exceptions::new_exception(Thread* thread, Symbol* name,
       
   395                                  const char* message,
       
   396                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
       
   397 
       
   398   Handle       h_loader(thread, NULL);
       
   399   Handle       h_prot(thread, NULL);
       
   400   Handle       h_cause(thread, NULL);
       
   401   return Exceptions::new_exception(thread, name, message, h_cause, h_loader,
       
   402                                    h_prot, to_utf8_safe);
       
   403 }
       
   404 
       
   405 
       
   406 // Exception counting for hs_err file
       
   407 volatile int Exceptions::_stack_overflow_errors = 0;
       
   408 volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0;
       
   409 volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0;
       
   410 volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0;
       
   411 
       
   412 void Exceptions::count_out_of_memory_exceptions(Handle exception) {
       
   413   if (exception() == Universe::out_of_memory_error_metaspace()) {
       
   414      Atomic::inc(&_out_of_memory_error_metaspace_errors);
       
   415   } else if (exception() == Universe::out_of_memory_error_class_metaspace()) {
       
   416      Atomic::inc(&_out_of_memory_error_class_metaspace_errors);
       
   417   } else {
       
   418      // everything else reported as java heap OOM
       
   419      Atomic::inc(&_out_of_memory_error_java_heap_errors);
       
   420   }
       
   421 }
       
   422 
       
   423 void print_oom_count(outputStream* st, const char *err, int count) {
       
   424   if (count > 0) {
       
   425     st->print_cr("OutOfMemoryError %s=%d", err, count);
       
   426   }
       
   427 }
       
   428 
       
   429 bool Exceptions::has_exception_counts() {
       
   430   return (_stack_overflow_errors + _out_of_memory_error_java_heap_errors +
       
   431          _out_of_memory_error_metaspace_errors + _out_of_memory_error_class_metaspace_errors) > 0;
       
   432 }
       
   433 
       
   434 void Exceptions::print_exception_counts_on_error(outputStream* st) {
       
   435   print_oom_count(st, "java_heap_errors", _out_of_memory_error_java_heap_errors);
       
   436   print_oom_count(st, "metaspace_errors", _out_of_memory_error_metaspace_errors);
       
   437   print_oom_count(st, "class_metaspace_errors", _out_of_memory_error_class_metaspace_errors);
       
   438   if (_stack_overflow_errors > 0) {
       
   439     st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors);
       
   440   }
       
   441 }
       
   442 
       
   443 // Implementation of ExceptionMark
       
   444 
       
   445 ExceptionMark::ExceptionMark(Thread*& thread) {
       
   446   thread     = Thread::current();
       
   447   _thread    = thread;
       
   448   if (_thread->has_pending_exception()) {
       
   449     oop exception = _thread->pending_exception();
       
   450     _thread->clear_pending_exception(); // Needed to avoid infinite recursion
       
   451     exception->print();
       
   452     fatal("ExceptionMark constructor expects no pending exceptions");
       
   453   }
       
   454 }
       
   455 
       
   456 
       
   457 ExceptionMark::~ExceptionMark() {
       
   458   if (_thread->has_pending_exception()) {
       
   459     Handle exception(_thread, _thread->pending_exception());
       
   460     _thread->clear_pending_exception(); // Needed to avoid infinite recursion
       
   461     if (is_init_completed()) {
       
   462       exception->print();
       
   463       fatal("ExceptionMark destructor expects no pending exceptions");
       
   464     } else {
       
   465       vm_exit_during_initialization(exception);
       
   466     }
       
   467   }
       
   468 }
       
   469 
       
   470 // ----------------------------------------------------------------------------------------
       
   471 
       
   472 // caller frees value_string if necessary
       
   473 void Exceptions::debug_check_abort(const char *value_string, const char* message) {
       
   474   if (AbortVMOnException != NULL && value_string != NULL &&
       
   475       strstr(value_string, AbortVMOnException)) {
       
   476     if (AbortVMOnExceptionMessage == NULL || (message != NULL &&
       
   477         strstr(message, AbortVMOnExceptionMessage))) {
       
   478       fatal("Saw %s, aborting", value_string);
       
   479     }
       
   480   }
       
   481 }
       
   482 
       
   483 void Exceptions::debug_check_abort(Handle exception, const char* message) {
       
   484   if (AbortVMOnException != NULL) {
       
   485     debug_check_abort_helper(exception, message);
       
   486   }
       
   487 }
       
   488 
       
   489 void Exceptions::debug_check_abort_helper(Handle exception, const char* message) {
       
   490   ResourceMark rm;
       
   491   if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) {
       
   492     oop msg = java_lang_Throwable::message(exception());
       
   493     if (msg != NULL) {
       
   494       message = java_lang_String::as_utf8_string(msg);
       
   495     }
       
   496   }
       
   497   debug_check_abort(exception()->klass()->external_name(), message);
       
   498 }
       
   499 
       
   500 // for logging exceptions
       
   501 void Exceptions::log_exception(Handle exception, stringStream tempst) {
       
   502   ResourceMark rm;
       
   503   Symbol* message = java_lang_Throwable::detail_message(exception());
       
   504   if (message != NULL) {
       
   505     log_info(exceptions)("Exception <%s: %s>\n thrown in %s",
       
   506                          exception->print_value_string(),
       
   507                          message->as_C_string(),
       
   508                          tempst.as_string());
       
   509   } else {
       
   510     log_info(exceptions)("Exception <%s>\n thrown in %s",
       
   511                          exception->print_value_string(),
       
   512                          tempst.as_string());
       
   513   }
       
   514 }