From a1a27c603009a7b9101c6f672845e415f58571d7 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 11 Jan 2017 16:37:16 -0800 Subject: ART: Add GetAllStackTraces Add support for GetAllStackTraces. Add a test. Bug: 31684812 Test: m test-art-host-run-test-911-get-stack-trace Change-Id: I81f783a6b37bfc7b68c10ba6c803a11e1bd5d350 --- test/911-get-stack-trace/src/Main.java | 98 +++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) (limited to 'test/911-get-stack-trace/src/Main.java') diff --git a/test/911-get-stack-trace/src/Main.java b/test/911-get-stack-trace/src/Main.java index 722bee8056..500e945ddd 100644 --- a/test/911-get-stack-trace/src/Main.java +++ b/test/911-get-stack-trace/src/Main.java @@ -14,7 +14,10 @@ * limitations under the License. */ +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.concurrent.CountDownLatch; public class Main { @@ -24,6 +27,10 @@ public class Main { doTest(); doTestOtherThreadWait(); doTestOtherThreadBusyLoop(); + + doTestAllStackTraces(); + + System.out.println("Done"); } public static void doTest() throws Exception { @@ -109,6 +116,47 @@ public class Main { t.join(); } + public static void doTestAllStackTraces() throws Exception { + System.out.println(); + System.out.println("################################"); + System.out.println("### Other threads (suspended) ###"); + System.out.println("################################"); + + final int N = 10; + + final ControlData data = new ControlData(N); + data.waitFor = new Object(); + + Thread threads[] = new Thread[N]; + + for (int i = 0; i < N; i++) { + Thread t = new Thread() { + public void run() { + Recurse.foo(4, 0, 0, data); + } + }; + t.start(); + threads[i] = t; + } + data.reached.await(); + Thread.yield(); + Thread.sleep(500); // A little bit of time... + + printAll(0); + + printAll(5); + + printAll(25); + + // Let the thread make progress and die. + synchronized(data.waitFor) { + data.waitFor.notifyAll(); + } + for (int i = 0; i < N; i++) { + threads[i].join(); + } + } + public static void print(String[][] stack) { System.out.println("---------"); for (String[] stackElement : stack) { @@ -124,6 +172,42 @@ public class Main { print(getStackTrace(t, start, max)); } + public static void printAll(Object[][] stacks) { + List stringified = new ArrayList(stacks.length); + + for (Object[] stackInfo : stacks) { + Thread t = (Thread)stackInfo[0]; + String name = (t != null) ? t.getName() : "null"; + String stackSerialization; + if (name.contains("Daemon")) { + // Do not print daemon stacks, as they're non-deterministic. + stackSerialization = ""; + } else { + StringBuilder sb = new StringBuilder(); + for (String[] stackElement : (String[][])stackInfo[1]) { + for (String part : stackElement) { + sb.append(' '); + sb.append(part); + } + sb.append('\n'); + } + stackSerialization = sb.toString(); + } + stringified.add(name + "\n" + stackSerialization); + } + + Collections.sort(stringified); + + for (String s : stringified) { + System.out.println("---------"); + System.out.println(s); + } + } + + public static void printAll(int max) { + printAll(getAllStackTraces(max)); + } + // Wrap generated stack traces into a class to separate them nicely. public static class Recurse { @@ -170,10 +254,22 @@ public class Main { } public static class ControlData { - CountDownLatch reached = new CountDownLatch(1); + CountDownLatch reached; Object waitFor = null; volatile boolean stop = false; + + public ControlData() { + this(1); + } + + public ControlData(int latchCount) { + reached = new CountDownLatch(latchCount); + } } public static native String[][] getStackTrace(Thread thread, int start, int max); + // Get all stack traces. This will return an array with an element for each thread. The element + // is an array itself with the first element being the thread, and the second element a nested + // String array as in getStackTrace. + public static native Object[][] getAllStackTraces(int max); } -- cgit v1.2.3-59-g8ed1b