1 /* 2 * Copyright 2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4919105 27 * @summary Generified basic unit test of Thread.getAllStackTraces() 28 * @author Mandy Chung 29 * 30 * @compile -source 1.5 GenerifyStackTraces.java 31 * @run main GenerifyStackTraces 32 */ 33 34 import java.util.*; 35 36 public class GenerifyStackTraces { 37 38 private static Object go = new Object(); 39 private static Object dumpObj = new Object(); 40 private static String[] methodNames = {"run", "A", "B", "C", "Done"}; 41 private static int DONE_DEPTH = 5; 42 private static boolean testFailed = false; 43 44 private static Thread one; 45 private static boolean trace = false; 46 public static void main(String[] args) throws Exception { 47 if (args.length > 0 && args[0].equals("trace")) { 48 trace = true; 49 } 50 51 one = new ThreadOne(); 52 one.start(); 53 54 Thread dt = new DumpThread(); 55 dt.setDaemon(true); 56 dt.start(); 57 58 if (testFailed) { 59 throw new RuntimeException("Test Failed."); 60 } 61 } 62 63 static class DumpThread extends Thread { 64 public void run() { 65 int depth = 2; 66 while (true) { 67 // At each iterator, wait until ThreadOne blocks 68 // to wait for thread dump. 69 // Then dump stack trace and notify ThreadOne to continue. 70 try { 71 sleep(2000); 72 dumpStacks(depth); 73 depth++; 74 finishDump(); 75 } catch (Exception e) { 76 e.printStackTrace(); 77 testFailed = true; 78 } 79 } 80 } 81 } 82 83 static class ThreadOne extends Thread { 84 public void run() { 85 A(); 86 } 87 private void A() { 88 waitForDump(); 89 B(); 90 } 91 private void B() { 92 waitForDump(); 93 C(); 94 } 95 private void C() { 96 waitForDump(); 97 Done(); 98 } 99 private void Done() { 100 waitForDump(); 101 102 // Get stack trace of current thread 103 StackTraceElement[] stack = getStackTrace(); 104 try { 105 checkStack(this, stack, DONE_DEPTH); 106 } catch (Exception e) { 107 e.printStackTrace(); 108 testFailed = true; 109 } 110 } 111 112 } 113 114 115 static private void waitForDump() { 116 synchronized(go) { 117 try { 118 go.wait(); 119 } catch (Exception e) { 120 throw new RuntimeException("Unexpected exception" + e); 121 } 122 } 123 } 124 125 static private void finishDump() { 126 synchronized(go) { 127 try { 128 go.notifyAll(); 129 } catch (Exception e) { 130 throw new RuntimeException("Unexpected exception" + e); 131 } 132 } 133 } 134 135 public static void dumpStacks(int depth) throws Exception { 136 // Get stack trace of another thread 137 StackTraceElement[] stack = one.getStackTrace(); 138 checkStack(one, stack, depth); 139 140 141 // Get stack traces of all Threads 142 for (Map.Entry<Thread, StackTraceElement[]> entry : 143 Thread.getAllStackTraces().entrySet()) { 144 Thread t = entry.getKey(); 145 stack = entry.getValue(); 146 if (t == null || stack == null) { 147 throw new RuntimeException("Null thread or stacktrace returned"); 148 } 149 if (t == one) { 150 checkStack(t, stack, depth); 151 } 152 } 153 } 154 155 private static void checkStack(Thread t, StackTraceElement[] stack, 156 int depth) throws Exception { 157 if (trace) { 158 printStack(t, stack); 159 } 160 int frame = stack.length - 1; 161 for (int i = 0; i < depth; i++) { 162 if (! stack[frame].getMethodName().equals(methodNames[i])) { 163 throw new RuntimeException("Expected " + methodNames[i] + 164 " in frame " + frame + " but got " + 165 stack[frame].getMethodName()); 166 } 167 frame--; 168 } 169 } 170 171 private static void printStack(Thread t, StackTraceElement[] stack) { 172 System.out.println(t + 173 " stack: (length = " + stack.length + ")"); 174 if (t != null) { 175 for (int j = 0; j < stack.length; j++) { 176 System.out.println(stack[j]); 177 } 178 System.out.println(); 179 } 180 } 181 }