From a75216a09c52b3304fad89ebdca5dd30b1ffca0d Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Fri, 8 Jan 2016 13:14:30 -0800 Subject: [PATCH] 8144552: java/lang/StackWalker/LocalsAndOperands.java fails with java.lang.NullPointerException Update test case to expect null Reviewed-by: mchung, dfuchs --- .../classes/java/lang/LiveStackFrame.java | 3 +++ .../lang/StackWalker/LocalsAndOperands.java | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java index 1ef4a2aa041..5be48729d5a 100644 --- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java +++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java @@ -61,6 +61,9 @@ interface LiveStackFrame extends StackFrame { * local variable array is an {@link PrimitiveValue} object; * otherwise, the element is an {@code Object}. * + *

The returned array may contain null entries if a local variable is not + * live. + * * @return the local variable array of this stack frame. */ public Object[] getLocals(); diff --git a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java index a296c788259..63a6731a164 100644 --- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java +++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java @@ -86,29 +86,43 @@ public class LocalsAndOperands { System.out.println("frame: " + f); Object[] locals = (Object[]) getLocals.invoke(f); for (int i = 0; i < locals.length; i++) { - System.out.format("local %d: %s type %s%n", i, locals[i], type(locals[i])); + System.out.format(" local %d: %s type %s\n", i, locals[i], type(locals[i])); + + // check for non-null locals in LocalsAndOperands.test() + if (f.getClassName().equals("LocalsAndOperands") && + f.getMethodName().equals("test")) { + if (locals[i] == null) { + throw new RuntimeException("kept-alive locals should not be null"); + } + } } Object[] operands = (Object[]) getOperands.invoke(f); for (int i = 0; i < operands.length; i++) { - System.out.format("operand %d: %s type %s%n", i, operands[i], type(operands[i])); + System.out.format(" operand %d: %s type %s%n", i, operands[i], + type(operands[i])); } Object[] monitors = (Object[]) getMonitors.invoke(f); for (int i = 0; i < monitors.length; i++) { - System.out.format("monitor %d: %s%n", i, monitors[i]); + System.out.format(" monitor %d: %s%n", i, monitors[i]); } } } else { for (StackFrame f : frames) { - if (liveStackFrameClass.isInstance(f)) + if (liveStackFrameClass.isInstance(f)) { throw new RuntimeException("should not be LiveStackFrame"); + } } } + // Use local variables so they stay alive + System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d); } String type(Object o) throws Exception { - if (primitiveValueClass.isInstance(o)) { + if (o == null) { + return "null"; + } else if (primitiveValueClass.isInstance(o)) { char c = (char)primitiveType.invoke(o); return String.valueOf(c); } else {