1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 import java.lang.management.*; 24 25 /* 26 * @test 27 * @bug 8205878 8206954 28 * @requires os.family != "windows" & os.family != "solaris" 29 * @summary Basic test of Thread and ThreadMXBean queries on a natively 30 * attached thread that has failed to detach before terminating. 31 * @comment The native code only supports POSIX so no windows testing; also 32 * we have to skip solaris as a terminating thread that fails to 33 * detach will hit an infinite loop due to TLS destructor issues - see 34 * comments in JDK-8156708 35 * @run main/othervm/native TestTerminatedThread 36 */ 37 38 public class TestTerminatedThread { 39 40 static native Thread createTerminatedThread(); 41 42 static { 43 System.loadLibrary("terminatedThread"); 44 } 45 46 private static ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); 47 48 public static void main(String[] args) throws Throwable { 49 50 Thread t = createTerminatedThread(); 51 52 if (!t.isAlive()) 53 throw new Error("Thread is only supposed to terminate at native layer!"); 54 55 // Now invoke the various functions on this thread to 56 // make sure the VM handles it okay. The focus is on 57 // functions with an underlying native OS implementation. 58 // Generally as long as we don't crash or throw unexpected 59 // exceptions then the test passes. In some cases we know exactly 60 // what a function should return and so can check that. 61 62 System.out.println("Working with thread: " + t + 63 ", in state: " + t.getState()); 64 65 System.out.println("Calling suspend ..."); 66 t.suspend(); 67 System.out.println("Calling resume ..."); 68 t.resume(); 69 System.out.println("Calling getStackTrace ..."); 70 StackTraceElement[] stack = t.getStackTrace(); 71 System.out.println(java.util.Arrays.toString(stack)); 72 if (stack.length != 0) 73 throw new Error("Terminated thread should have empty java stack trace"); 74 System.out.println("Calling setName(\"NewName\") ..."); 75 t.setName("NewName"); 76 System.out.println("Calling interrupt ..."); 77 t.interrupt(); 78 System.out.println("Calling stop ..."); 79 t.stop(); 80 81 // Now the ThreadMXBean functions 82 83 if (mbean.isThreadCpuTimeSupported() && 84 mbean.isThreadCpuTimeEnabled() ) { 85 System.out.println("Calling getThreadCpuTime ..."); 86 long t1 = mbean.getThreadCpuTime(t.getId()); 87 if (t1 != -1) { 88 // At least on PPC, we know threads can still be around a short 89 // instant. In some stress scenarios we seem to grab times of 90 // new threads started with the same thread id. In these cases 91 // we get here. 92 System.out.println("Unexpected: thread still reports CPU time: " + t1); 93 } else { 94 System.out.println("Okay: getThreadCpuTime() reported -1 as expected"); 95 } 96 } else { 97 System.out.println("Skipping Thread CPU time test as it's not supported"); 98 } 99 100 System.out.println("Calling getThreadUserTime ..."); 101 long t1 = mbean.getThreadUserTime(t.getId()); 102 if (t1 != -1) { 103 // At least on PPC, we know threads can still be around a short 104 // instant. In some stress scenarios we seem to grab times of 105 // new threads started with the same thread id. In these cases 106 // we get here. 107 System.out.println("Unexpected: thread still reports User time: " + t1); 108 } else { 109 System.out.println("Okay: getThreadUserTime() reported -1 as expected"); 110 } 111 112 System.out.println("Calling getThreadInfo ..."); 113 ThreadInfo info = mbean.getThreadInfo(t.getId()); 114 System.out.println(info); 115 116 System.out.println("Calling getThreadInfo with stack ..."); 117 info = mbean.getThreadInfo(t.getId(), Integer.MAX_VALUE); 118 System.out.println(info); 119 } 120 }