From 40807f0a8e2ec5aeb1fdf457aa94d8ef1261e1de Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 20 Mar 2015 01:59:08 -0700 Subject: [PATCH] 8067662: "java.lang.NullPointerException: Method name is null" from StackTraceElement. Update java/lang/instrument/RedefineMethodInBacktrace.sh test to cover the hotspot fix Reviewed-by: coleenp, dcubed --- .../instrument/RedefineMethodInBacktrace.sh | 2 +- .../RedefineMethodInBacktraceApp.java | 56 +++++++++++++++++-- .../RedefineMethodInBacktraceTarget.java | 9 +++ .../RedefineMethodInBacktraceTargetB.java | 12 ++++ .../RedefineMethodInBacktraceTargetB_2.java | 3 + .../RedefineMethodInBacktraceTarget_2.java | 4 ++ 6 files changed, 80 insertions(+), 6 deletions(-) diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh index 4ebaaa8e73b..439a7f72776 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh @@ -77,7 +77,7 @@ fi cat output.log -MESG="Exception" +MESG="Test failed" grep "$MESG" output.log result=$? if [ "$result" = 0 ]; then diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java index 7f7ddbf19b1..60ab8e4347a 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java @@ -46,12 +46,15 @@ import sun.management.ManagementFactoryHelper; * could be freed, since class redefinition didn't know about the backtraces. */ public class RedefineMethodInBacktraceApp { + static boolean failed = false; + public static void main(String args[]) throws Exception { System.out.println("Hello from RedefineMethodInBacktraceApp!"); - new RedefineMethodInBacktraceApp().doTest(); - System.exit(0); + if (failed) { + throw new Exception("ERROR: RedefineMethodInBacktraceApp failed."); + } } public static CountDownLatch stop = new CountDownLatch(1); @@ -63,13 +66,18 @@ public class RedefineMethodInBacktraceApp { } private void doMethodInBacktraceTest() throws Exception { - Throwable t = getThrowableFromMethodToRedefine(); + Throwable t1 = getThrowableFromMethodToRedefine(); + Throwable t2 = getThrowableFromMethodToDelete(); doRedefine(RedefineMethodInBacktraceTarget.class); doClassUnloading(); - touchRedefinedMethodInBacktrace(t); + System.out.println("checking backtrace for throwable from methodToRedefine"); + touchRedefinedMethodInBacktrace(t1); + + System.out.println("checking backtrace for throwable from methodToDelete"); + touchRedefinedMethodInBacktrace(t2); } private void doMethodInBacktraceTestB() throws Exception { @@ -115,6 +123,10 @@ public class RedefineMethodInBacktraceApp { if (!(thrownFromMethodToRedefine instanceof RuntimeException)) { throw e; } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("\nTest failed: unexpected exception: " + e.toString()); + failed = true; } method = null; c = null; @@ -122,15 +134,49 @@ public class RedefineMethodInBacktraceApp { return thrownFromMethodToRedefine; } + private static Throwable getThrowableFromMethodToDelete() throws Exception { + Class c = + RedefineMethodInBacktraceTarget.class; + Method method = c.getMethod("callMethodToDelete"); + + Throwable thrownFromMethodToDelete = null; + try { + method.invoke(null); + } catch (InvocationTargetException e) { + thrownFromMethodToDelete = e.getCause(); + if (!(thrownFromMethodToDelete instanceof RuntimeException)) { + throw e; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("\nTest failed: unexpected exception: " + e.toString()); + failed = true; + } + return thrownFromMethodToDelete; + } + + private static void doClassUnloading() { // This will clean out old, unused redefined methods. System.gc(); } private static void touchRedefinedMethodInBacktrace(Throwable throwable) { + throwable.printStackTrace(); // Make sure that we can convert the backtrace, which is referring to // the redefined method, to a StrackTraceElement[] without crashing. - throwable.getStackTrace(); + StackTraceElement[] stackTrace = throwable.getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) { + StackTraceElement frame = stackTrace[i]; + if (frame.getClassName() == null) { + System.out.println("\nTest failed: trace[" + i + "].getClassName() returned null"); + failed = true; + } + if (frame.getMethodName() == null) { + System.out.println("\nTest failed: trace[" + i + "].getMethodName() returned null"); + failed = true; + } + } } private static void doRedefine(Class clazz) throws Exception { diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java index fad881137c8..d1c1e33078d 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java @@ -29,4 +29,13 @@ public class RedefineMethodInBacktraceTarget { public static void methodToRedefine() { throw new RuntimeException("Test exception"); } + + public static void callMethodToDelete() { + methodToDelete(); + } + + private static void methodToDelete() { + throw new RuntimeException("Test exception in methodToDelete"); + } + } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java index baefeb78703..d7fb6f7857a 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java @@ -37,4 +37,16 @@ public class RedefineMethodInBacktraceTargetB { // ignore, test will fail } } + + public static void callMethodToDelete() { + try { + // signal that we are here + RedefineMethodInBacktraceApp.called.countDown(); + + // wait until test is done + RedefineMethodInBacktraceApp.stop.await(); + } catch (InterruptedException ex) { + // ignore, test will fail + } + } } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java index de98206a8dd..33c6e7103e2 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java @@ -28,4 +28,7 @@ public class RedefineMethodInBacktraceTargetB { public static void methodToRedefine() { } + + public static void callMethodToDelete() { + } } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java index d2ba2259932..a7d9dc666a1 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java @@ -29,4 +29,8 @@ public class RedefineMethodInBacktraceTarget { public static void methodToRedefine() { throw new RuntimeException("Test exception 2"); } + + public static void callMethodToDelete() { + throw new RuntimeException("Test exception 2 in callMethodToDelete"); + } }