Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java
38821 views
/*1* Copyright (c) 2003, 2004, 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 Semaphore Utils31* @run main ThreadStackTrace32*/3334import java.lang.management.*;3536public class ThreadStackTrace {37private static ThreadMXBean mbean38= ManagementFactory.getThreadMXBean();39private static boolean notified = false;40private static Object lockA = new Object();41private static Object lockB = new Object();42private static volatile boolean testFailed = false;43private static String[] blockedStack = {"run", "test", "A", "B", "C", "D"};44private static int bsDepth = 6;45private static int methodB = 4;46private static String[] examinerStack = {"run", "examine1", "examine2"};47private static int esDepth = 3;48private static int methodExamine1= 2;4950private static void checkNullThreadInfo(Thread t) throws Exception {51ThreadInfo ti = mbean.getThreadInfo(t.getId());52if (ti != null) {53ThreadInfo info =54mbean.getThreadInfo(t.getId(), Integer.MAX_VALUE);55System.out.println(INDENT + "TEST FAILED:");56if (info != null) {57printStack(t, info.getStackTrace());58System.out.println(INDENT + "Thread state: " + info.getThreadState());59}60throw new RuntimeException("TEST FAILED: " +61"getThreadInfo() is expected to return null for " + t);62}63}6465private static boolean trace = false;66public static void main(String args[]) throws Exception {67if (args.length > 0 && args[0].equals("trace")) {68trace = true;69}7071Examiner examiner = new Examiner("Examiner");72BlockedThread blocked = new BlockedThread("BlockedThread");73examiner.setThread(blocked);7475checkNullThreadInfo(examiner);76checkNullThreadInfo(blocked);7778// Start the threads and check them in Blocked and Waiting states79examiner.start();8081// block until examiner begins doing its real work82examiner.waitForStarted();8384System.out.println("Checking stack trace for the examiner thread " +85"is waiting to begin.");8687// The Examiner should be waiting to be notified by the BlockedThread88Utils.checkThreadState(examiner, Thread.State.WAITING);8990// Check that the stack is returned correctly for a new thread91checkStack(examiner, examinerStack, esDepth);9293System.out.println("Now starting the blocked thread");94blocked.start();9596try {97examiner.join();98blocked.join();99} catch (InterruptedException e) {100e.printStackTrace();101System.out.println("Unexpected exception.");102testFailed = true;103}104105// Check that the stack is returned correctly for a terminated thread106checkNullThreadInfo(examiner);107checkNullThreadInfo(blocked);108109if (testFailed)110throw new RuntimeException("TEST FAILED.");111112System.out.println("Test passed.");113}114115private static String INDENT = " ";116private static void printStack(Thread t, StackTraceElement[] stack) {117System.out.println(INDENT + t +118" stack: (length = " + stack.length + ")");119if (t != null) {120for (int j = 0; j < stack.length; j++) {121System.out.println(INDENT + stack[j]);122}123System.out.println();124}125}126127private static void checkStack(Thread t, String[] expectedStack,128int depth) throws Exception {129ThreadInfo ti = mbean.getThreadInfo(t.getId(), Integer.MAX_VALUE);130StackTraceElement[] stack = ti.getStackTrace();131132if (trace) {133printStack(t, stack);134}135int frame = stack.length - 1;136for (int i = 0; i < depth; i++) {137if (! stack[frame].getMethodName().equals(expectedStack[i])) {138throw new RuntimeException("TEST FAILED: " +139"Expected " + expectedStack[i] + " in frame " + frame +140" but got " + stack[frame].getMethodName());141}142frame--;143}144}145146static class BlockedThread extends Thread {147private Semaphore handshake = new Semaphore();148149BlockedThread(String name) {150super(name);151}152boolean hasWaitersForBlocked() {153return (handshake.getWaiterCount() > 0);154}155156void waitUntilBlocked() {157handshake.semaP();158159// give a chance for the examiner thread to really wait160Utils.goSleep(20);161}162163void waitUntilLockAReleased() {164handshake.semaP();165166// give a chance for the examiner thread to really wait167Utils.goSleep(50);168}169170private void notifyWaiter() {171// wait until the examiner waits on the semaphore172while (handshake.getWaiterCount() == 0) {173Utils.goSleep(20);174}175handshake.semaV();176}177178private void test() {179A();180}181private void A() {182B();183}184private void B() {185C();186187// notify the examiner about to block on lockB188notifyWaiter();189190synchronized (lockB) {191};192}193private void C() {194D();195}196private void D() {197// Notify that examiner about to enter lockA198notifyWaiter();199200synchronized (lockA) {201notified = false;202while (!notified) {203try {204// notify the examiner about to release lockA205notifyWaiter();206// Wait and let examiner thread check the mbean207lockA.wait();208} catch (InterruptedException e) {209e.printStackTrace();210System.out.println("Unexpected exception.");211testFailed = true;212}213}214System.out.println("BlockedThread notified");215}216}217218public void run() {219test();220} // run()221} // BlockedThread222223static class Examiner extends Thread {224private static BlockedThread blockedThread;225private Semaphore handshake = new Semaphore();226227Examiner(String name) {228super(name);229}230231public void setThread(BlockedThread thread) {232blockedThread = thread;233}234235public synchronized void waitForStarted() {236// wait until the examiner is about to block237handshake.semaP();238239// wait until the examiner is waiting for blockedThread's notification240while (!blockedThread.hasWaitersForBlocked()) {241Utils.goSleep(50);242}243// give a chance for the examiner thread to really wait244Utils.goSleep(20);245}246247private Thread itself;248private void examine1() {249synchronized (lockB) {250examine2();251try {252System.out.println("Checking examiner's its own stack trace");253Utils.checkThreadState(itself, Thread.State.RUNNABLE);254checkStack(itself, examinerStack, methodExamine1);255256// wait until blockedThread is blocked on lockB257blockedThread.waitUntilBlocked();258259System.out.println("Checking stack trace for " +260"BlockedThread - should be blocked on lockB.");261Utils.checkThreadState(blockedThread, Thread.State.BLOCKED);262checkStack(blockedThread, blockedStack, methodB);263} catch (Exception e) {264e.printStackTrace();265System.out.println("Unexpected exception.");266testFailed = true;267}268}269}270271private void examine2() {272synchronized (lockA) {273// wait until main thread gets signalled of the semaphore274while (handshake.getWaiterCount() == 0) {275Utils.goSleep(20);276}277278handshake.semaV(); // notify the main thread279try {280// Wait until BlockedThread is about to block on lockA281blockedThread.waitUntilBlocked();282283System.out.println("Checking examiner's its own stack trace");284Utils.checkThreadState(itself, Thread.State.RUNNABLE);285checkStack(itself, examinerStack, esDepth);286287System.out.println("Checking stack trace for " +288"BlockedThread - should be blocked on lockA.");289Utils.checkThreadState(blockedThread, Thread.State.BLOCKED);290checkStack(blockedThread, blockedStack, bsDepth);291292} catch (Exception e) {293e.printStackTrace();294System.out.println("Unexpected exception.");295testFailed = true;296}297}298299// release lockA and let BlockedThread to get the lock300// and wait on lockA301blockedThread.waitUntilLockAReleased();302303synchronized (lockA) {304try {305System.out.println("Checking stack trace for " +306"BlockedThread - should be waiting on lockA.");307Utils.checkThreadState(blockedThread, Thread.State.WAITING);308checkStack(blockedThread, blockedStack, bsDepth);309310// Let the blocked thread go311notified = true;312lockA.notify();313} catch (Exception e) {314e.printStackTrace();315System.out.println("Unexpected exception.");316testFailed = true;317}318}319// give some time for BlockedThread to proceed320Utils.goSleep(50);321} // examine2()322323public void run() {324itself = Thread.currentThread();325examine1();326} // run()327} // Examiner328}329330331