Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/ThreadStackTrace.java
41152 views
/*1* Copyright (c) 2003, 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 453053826* @summary Basic unit test of ThreadInfo.getStackTrace() and27* ThreadInfo.getThreadState()28* @author Mandy Chung29*30* @run build Utils31* @run main ThreadStackTrace32*/3334import java.lang.management.*;35import java.util.concurrent.Phaser;3637public class ThreadStackTrace {38private static final ThreadMXBean mbean39= ManagementFactory.getThreadMXBean();40private static boolean notified = false;41private static final Object lockA = new Object();42private static final Object lockB = new Object();43private static volatile boolean testFailed = false;44private static final String[] blockedStack = {"run", "test", "A", "B", "C", "D"};45private static final int bsDepth = 6;46private static final int methodB = 4;47private static final String[] examinerStack = {"run", "examine1", "examine2"};48private static final int esDepth = 3;49private static final int methodExamine1= 2;5051private static void checkNullThreadInfo(Thread t) throws Exception {52ThreadInfo ti = mbean.getThreadInfo(t.getId());53if (ti != null) {54ThreadInfo info =55mbean.getThreadInfo(t.getId(), Integer.MAX_VALUE);56System.out.println(INDENT + "TEST FAILED:");57if (info != null) {58printStack(t, info.getStackTrace());59System.out.println(INDENT + "Thread state: " + info.getThreadState());60}61throw new RuntimeException("TEST FAILED: " +62"getThreadInfo() is expected to return null for " + t);63}64}6566private static boolean trace = false;67public static void main(String args[]) throws Exception {68if (args.length > 0 && args[0].equals("trace")) {69trace = true;70}7172final Phaser p = new Phaser(2);7374Examiner examiner = new Examiner("Examiner", p);75BlockedThread blocked = new BlockedThread("BlockedThread", p);76examiner.setThread(blocked);7778checkNullThreadInfo(examiner);79checkNullThreadInfo(blocked);8081// Start the threads and check them in Blocked and Waiting states82examiner.start();8384// #1 - block until examiner begins doing its real work85p.arriveAndAwaitAdvance();8687System.out.println("Checking stack trace for the examiner thread " +88"is waiting to begin.");8990// The Examiner should be waiting to be notified by the BlockedThread91Utils.checkThreadState(examiner, Thread.State.WAITING);9293// Check that the stack is returned correctly for a new thread94checkStack(examiner, examinerStack, esDepth);9596System.out.println("Now starting the blocked thread");97blocked.start();9899try {100examiner.join();101blocked.join();102} catch (InterruptedException e) {103e.printStackTrace();104System.out.println("Unexpected exception.");105testFailed = true;106}107108// Check that the stack is returned correctly for a terminated thread109checkNullThreadInfo(examiner);110checkNullThreadInfo(blocked);111112if (testFailed)113throw new RuntimeException("TEST FAILED.");114115System.out.println("Test passed.");116}117118private static String INDENT = " ";119private static void printStack(Thread t, StackTraceElement[] stack) {120System.out.println(INDENT + t +121" stack: (length = " + stack.length + ")");122if (t != null) {123for (int j = 0; j < stack.length; j++) {124System.out.println(INDENT + stack[j]);125}126System.out.println();127}128}129130private static void checkStack(Thread t, String[] expectedStack,131int depth) throws Exception {132ThreadInfo ti = mbean.getThreadInfo(t.getId(), Integer.MAX_VALUE);133StackTraceElement[] stack = ti.getStackTrace();134135if (trace) {136printStack(t, stack);137}138int frame = stack.length - 1;139for (int i = 0; i < depth; i++) {140if (! stack[frame].getMethodName().equals(expectedStack[i])) {141throw new RuntimeException("TEST FAILED: " +142"Expected " + expectedStack[i] + " in frame " + frame +143" but got " + stack[frame].getMethodName());144}145frame--;146}147}148149static class BlockedThread extends Thread {150private final Phaser phaser;151152BlockedThread(String name, Phaser phaser) {153super(name);154this.phaser = phaser;155}156157private void test() {158A();159}160private void A() {161B();162}163private void B() {164C();165166// #4 - notify the examiner about to block on lockB167phaser.arriveAndAwaitAdvance();168169synchronized (lockB) {};170}171private void C() {172D();173}174private void D() {175// #2 - Notify that examiner about to enter lockA176phaser.arriveAndAwaitAdvance();177178synchronized (lockA) {179notified = false;180while (!notified) {181try {182// #3 - notify the examiner about to release lockA183phaser.arriveAndAwaitAdvance();184// Wait and let examiner thread check the mbean185lockA.wait();186} catch (InterruptedException e) {187e.printStackTrace();188System.out.println("Unexpected exception.");189testFailed = true;190}191}192System.out.println("BlockedThread notified");193}194}195196@Override197public void run() {198test();199} // run()200} // BlockedThread201202static class Examiner extends Thread {203private static BlockedThread blockedThread;204private final Phaser phaser;205206Examiner(String name, Phaser phaser) {207super(name);208this.phaser = phaser;209}210211public void setThread(BlockedThread thread) {212blockedThread = thread;213}214215private Thread itself;216private void examine1() {217synchronized (lockB) {218examine2();219try {220System.out.println("Checking examiner's its own stack trace");221Utils.checkThreadState(itself, Thread.State.RUNNABLE);222checkStack(itself, examinerStack, methodExamine1);223224// #4 - wait until blockedThread is blocked on lockB225phaser.arriveAndAwaitAdvance();226Utils.waitForThreadState(blockedThread, State.BLOCKED);227228System.out.println("Checking stack trace for " +229"BlockedThread - should be blocked on lockB.");230Utils.checkThreadState(blockedThread, Thread.State.BLOCKED);231checkStack(blockedThread, blockedStack, methodB);232} catch (Exception e) {233e.printStackTrace();234System.out.println("Unexpected exception.");235testFailed = true;236}237}238}239240private void examine2() {241synchronized (lockA) {242// #1 - examiner ready to do the real work243phaser.arriveAndAwaitAdvance();244try {245// #2 - Wait until BlockedThread is about to block on lockA246phaser.arriveAndAwaitAdvance();247Utils.waitForThreadState(blockedThread, State.BLOCKED);248249System.out.println("Checking examiner's its own stack trace");250Utils.checkThreadState(itself, Thread.State.RUNNABLE);251checkStack(itself, examinerStack, esDepth);252253System.out.println("Checking stack trace for " +254"BlockedThread - should be blocked on lockA.");255Utils.checkThreadState(blockedThread, Thread.State.BLOCKED);256checkStack(blockedThread, blockedStack, bsDepth);257258} catch (Exception e) {259e.printStackTrace();260System.out.println("Unexpected exception.");261testFailed = true;262}263}264265// #3 - release lockA and let BlockedThread to get the lock266// and wait on lockA267phaser.arriveAndAwaitAdvance();268Utils.waitForThreadState(blockedThread, State.WAITING);269270synchronized (lockA) {271try {272System.out.println("Checking stack trace for " +273"BlockedThread - should be waiting on lockA.");274Utils.checkThreadState(blockedThread, Thread.State.WAITING);275checkStack(blockedThread, blockedStack, bsDepth);276277// Let the blocked thread go278notified = true;279lockA.notify();280} catch (Exception e) {281e.printStackTrace();282System.out.println("Unexpected exception.");283testFailed = true;284}285}286// give some time for BlockedThread to proceed287Utils.goSleep(50);288} // examine2()289290@Override291public void run() {292itself = Thread.currentThread();293examine1();294} // run()295} // Examiner296}297298299