1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.ref.Reference; 18 import java.lang.ref.WeakReference; 19 import java.lang.ref.SoftReference; 20 import java.math.BigInteger; 21 import java.util.ArrayList; 22 23 /** 24 * We construct a main thread and worker threads, each retrieving stack traces 25 * from the other. Since there are multiple workers, we may get a large number 26 * of simultaneous stack trace attempts. 27 */ 28 public class Main { 29 static final int NUM_THREADS = 5; 30 static Thread mainThread; 31 static volatile boolean pleaseStop = false; 32 getTrace(Thread t)33 private static void getTrace(Thread t) { 34 StackTraceElement trace[] = t.getStackTrace(); 35 if (!pleaseStop && (trace.length < 1 || trace.length > 20)) { 36 // If called from traceGetter, we were started by the main thread, and it was still 37 // running after the trace, so the main thread should have at least one frame on 38 // the stack. If called by main(), we waited for all the traceGetters to start, 39 // and didn't yet allow them to stop, so the same should be true. 40 System.out.println("Stack trace for " + t.getName() + " has size " + trace.length); 41 for (StackTraceElement e : trace) { 42 System.out.println(e.toString()); 43 } 44 } 45 } 46 47 /** 48 * Repeatedly get and minimally check stack trace of main thread. 49 */ 50 static Runnable traceGetter = new Runnable() { 51 public void run() { 52 System.out.println("Starting helper"); 53 while (!pleaseStop) { 54 getTrace(mainThread); 55 } 56 } 57 }; 58 main(String[] args)59 public static void main(String[] args) throws Exception { 60 System.out.println("Starting"); 61 Thread[] t = new Thread[NUM_THREADS]; 62 mainThread = Thread.currentThread(); 63 for (int i = 0; i < NUM_THREADS; ++i) { 64 t[i] = new Thread(traceGetter); 65 t[i].start(); 66 } 67 try { 68 Thread.sleep(1000); 69 } catch (InterruptedException e) { 70 System.out.println("Unexpectedly interrupted"); 71 } 72 for (int i = 0; i < NUM_THREADS; ++i) { 73 getTrace(t[i]); 74 } 75 System.out.println("Finished worker stack traces"); 76 long now = System.currentTimeMillis(); 77 while (System.currentTimeMillis() - now < 2000) { 78 try { 79 Thread.sleep(1); 80 } catch (InterruptedException e) { 81 System.out.println("Unexpectedly interrupted"); 82 } 83 } 84 pleaseStop = true; 85 System.out.println("Finished"); 86 } 87 } 88