Path: blob/master/test/jdk/java/lang/StackWalker/DumpStackTest.java
41149 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 814321426* @summary Verify outputs of Thread.dumpStack() and Throwable.printStackTrace().27* This test should also been run against jdk9 successfully except of28* VM option MemberNameInStackFrame.29* @run main/othervm DumpStackTest30*/3132import java.lang.invoke.MethodHandle;33import java.lang.invoke.MethodHandles;34import java.lang.invoke.MethodType;35import java.lang.reflect.Method;36import java.util.Arrays;37import java.util.function.Consumer;3839public class DumpStackTest {4041public static void main(String args[]) {42test();43testThread();44testLambda();45testMethodInvoke();46testMethodHandle();47}4849static class CallFrame {50final String classname;51final String methodname;52CallFrame(Class<?> c, String methodname) {53this(c.getName(), methodname);54}55CallFrame(String classname, String methodname) {56this.classname = classname;57this.methodname = methodname;58}5960String getClassName() {61return classname;62}63String getMethodName() {64return methodname;65}66String getFileName() {67int i = classname.lastIndexOf('.');68int j = classname.lastIndexOf('$');69String name = classname.substring(i+1, j >= 0 ? j : classname.length());70return name + ".java";71}72@Override73public String toString() {74return classname + "." + methodname + "(" + getFileName() + ")";75}76}7778static void test() {79CallFrame[] callStack = new CallFrame[] {80new CallFrame(Thread.class, "getStackTrace"),81new CallFrame(DumpStackTest.class, "test"),82new CallFrame(DumpStackTest.class, "main"),83// if invoked from jtreg84new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke0"), // non-public class85new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke"),86new CallFrame("jdk.internal.reflect.DelegatingMethodAccessorImpl", "invoke"),87new CallFrame(Method.class, "invoke"),88new CallFrame(Thread.class, "run"),89};9091assertStackTrace(Thread.currentThread().getStackTrace(), callStack);92getStackTrace(callStack);93}9495static void getStackTrace(CallFrame[] callStack) {96// this method is the top of the stack97callStack[0] = new CallFrame(DumpStackTest.class, "getStackTrace");9899try {100throw new RuntimeException();101} catch(RuntimeException ex) {102assertStackTrace(ex.getStackTrace(), callStack);103}104}105static void testThread() {106Thread t1 = new Thread() {107public void run() {108c();109}110111void c() {112CallFrame[] callStack = new CallFrame[] {113new CallFrame(Thread.class, "getStackTrace"),114new CallFrame(this.getClass(), "c"),115new CallFrame(this.getClass(), "run")116};117assertStackTrace(Thread.currentThread().getStackTrace(), callStack);118DumpStackTest.getStackTrace(callStack);119}120};121t1.start();122try {123t1.join();124} catch(InterruptedException e) {}125}126127static void testLambda() {128Consumer<Void> c = (x) -> consumeLambda();129c.accept(null);130}131132static void consumeLambda() {133CallFrame[] callStack = new CallFrame[]{134new CallFrame(Thread.class, "getStackTrace"),135new CallFrame(DumpStackTest.class, "consumeLambda"),136new CallFrame(DumpStackTest.class, "lambda$testLambda$0"),137new CallFrame(DumpStackTest.class, "testLambda"),138new CallFrame(DumpStackTest.class, "main"),139// if invoked from jtreg140new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke0"),141new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke"),142new CallFrame("jdk.internal.reflect.DelegatingMethodAccessorImpl", "invoke"),143new CallFrame(Method.class, "invoke"),144new CallFrame(Thread.class, "run")145};146assertStackTrace(Thread.currentThread().getStackTrace(), callStack);147DumpStackTest.getStackTrace(callStack);148}149150static void testMethodInvoke() {151try {152Method m = DumpStackTest.class.getDeclaredMethod("methodInvoke");153m.invoke(null);154} catch(Exception e) {155throw new RuntimeException(e);156}157}158159static void methodInvoke() {160CallFrame[] callStack = new CallFrame[] {161new CallFrame(Thread.class, "getStackTrace"),162new CallFrame(DumpStackTest.class, "methodInvoke"),163new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke0"),164new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke"),165new CallFrame("jdk.internal.reflect.DelegatingMethodAccessorImpl", "invoke"),166new CallFrame(Method.class, "invoke"),167new CallFrame(DumpStackTest.class, "testMethodInvoke"),168new CallFrame(DumpStackTest.class, "main"),169// if invoked from jtreg170new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke0"),171new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke"),172new CallFrame("jdk.internal.reflect.DelegatingMethodAccessorImpl", "invoke"),173new CallFrame(Method.class, "invoke"),174new CallFrame(Thread.class, "run")175};176assertStackTrace(Thread.currentThread().getStackTrace(), callStack);177DumpStackTest.getStackTrace(callStack);178}179180static void testMethodHandle() {181MethodHandles.Lookup lookup = MethodHandles.lookup();182try {183MethodHandle handle = lookup.findStatic(DumpStackTest.class, "methodHandle",184MethodType.methodType(void.class));185handle.invoke();186} catch(Throwable t) {187throw new RuntimeException(t);188}189}190191static void methodHandle() {192CallFrame[] callStack = new CallFrame[]{193new CallFrame(Thread.class, "getStackTrace"),194new CallFrame(DumpStackTest.class, "methodHandle"),195new CallFrame(DumpStackTest.class, "testMethodHandle"),196new CallFrame(DumpStackTest.class, "main"),197// if invoked from jtreg198new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke0"),199new CallFrame("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke"),200new CallFrame("jdk.internal.reflect.DelegatingMethodAccessorImpl", "invoke"),201new CallFrame(Method.class, "invoke"),202new CallFrame(Thread.class, "run")203};204assertStackTrace(Thread.currentThread().getStackTrace(), callStack);205DumpStackTest.getStackTrace(callStack);206}207208static void assertStackTrace(StackTraceElement[] actual, CallFrame[] expected) {209System.out.println("--- Actual ---");210Arrays.stream(actual).forEach(e -> System.out.println(e));211System.out.println("--- Expected ---");212Arrays.stream(expected).forEach(e -> System.out.println(e));213214for (int i = 0, j = 0; i < actual.length; i++) {215// filter test framework classes216if (actual[i].getClassName().startsWith("com.sun.javatest.regtest"))217continue;218assertEquals(actual[i], expected[j++], i);219}220221}222static void assertEquals(StackTraceElement actual, CallFrame expected, int idx) {223if (!actual.getClassName().equals(expected.getClassName()) ||224!actual.getFileName().equals(expected.getFileName()) ||225!actual.getMethodName().equals(expected.getMethodName())) {226throw new RuntimeException("StackTraceElements mismatch at index " + idx +227". Expected [" + expected + "], but get [" + actual + "]");228}229}230}231232233