< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
rev 53693 : wq8218628: Add detailed message to NullPointerException describing what is null.

@@ -22,10 +22,11 @@
  *
  */
 
 #include "precompiled.hpp"
 #include "jvm.h"
+#include "classfile/bytecodeUtils.hpp"
 #include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/javaClasses.inline.hpp"

@@ -531,17 +532,60 @@
 
 
 
 // java.lang.Throwable //////////////////////////////////////////////////////
 
-
 JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver))
   JVMWrapper("JVM_FillInStackTrace");
   Handle exception(thread, JNIHandles::resolve_non_null(receiver));
   java_lang_Throwable::fill_in_stack_trace(exception);
 JVM_END
 
+// java.lang.NullPointerException ///////////////////////////////////////////
+
+JVM_ENTRY(jstring, JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwable, jstring defaultMessage))
+  if (!ExtendedExceptionMessages) {
+    return defaultMessage;
+  }
+
+  oop exc = JNIHandles::resolve_non_null(throwable);
+
+  Method* method;
+  int bci;
+  if (!java_lang_Throwable::get_method_and_bci(exc, 0, &method, &bci)) {
+    return defaultMessage;
+  }
+  if (method->is_native()) {
+    return defaultMessage;
+  }
+
+  ResourceMark rm(THREAD);
+  TrackingStackCreator stc(method, bci);
+  char const* reason;
+  int slot = stc.get_null_pointer_slot(bci, &reason);
+
+  // Build the message.
+  stringStream ss;
+  if (slot == -2) {
+    return defaultMessage;
+  } else if (slot == -1) {
+    ss.print("There cannot be a NullPointerException at bci %d of method %s",
+             bci, method->name_and_sig_as_C_string());
+  } else if (reason == NULL) {
+    ss.print("Cannot get the reason for the NullPointerException at bci %d of method %s",
+             bci, method->name_and_sig_as_C_string());
+  } else {
+    TrackingStackSource source = stc.get_source(bci, slot, ExtendedExceptionMessagesMaxDepth);
+    ss.print("%s", reason);
+    if (source.get_type() != TrackingStackSource::INVALID) {
+      ss.print(" %s", source.as_string());
+    }
+  }
+
+  oop result = java_lang_String::create_oop_from_str(ss.as_string(), CHECK_0);
+  return (jstring) JNIHandles::make_local(env, result);
+JVM_END
 
 // java.lang.StackTraceElement //////////////////////////////////////////////
 
 
 JVM_ENTRY(void, JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable))
< prev index next >