1 /* 2 * Copyright (C) 2016 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 package art; 18 19 import java.util.ArrayList; 20 import java.util.Collections; 21 import java.util.List; 22 import java.util.regex.Matcher; 23 import java.util.regex.Pattern; 24 25 public class PrintThread { print(String[][] stack)26 public static void print(String[][] stack) { 27 System.out.println("---------"); 28 for (String[] stackElement : stack) { 29 for (String part : stackElement) { 30 System.out.print(' '); 31 System.out.print(part); 32 } 33 System.out.println(); 34 } 35 } 36 print(Thread t, int start, int max)37 public static void print(Thread t, int start, int max) { 38 print(getStackTrace(t, start, max)); 39 } 40 41 // We have to ignore some threads when printing all stack traces. These are threads that may or 42 // may not exist depending on the environment. 43 public final static String IGNORE_THREAD_NAME_REGEX = 44 "Binder:|RenderThread|hwuiTask|Jit thread pool worker|Instr:|JDWP|Profile Saver|main|" + 45 "queued-work-looper|InstrumentationConnectionThread|intel_svc_streamer_thread|ForkJoinPool"; 46 public final static Matcher IGNORE_THREADS = 47 Pattern.compile(IGNORE_THREAD_NAME_REGEX).matcher(""); 48 49 // We have to skip the stack of some threads when printing all stack traces. These are threads 50 // that may have a different call stack (e.g., when run as an app), or may be in a 51 // non-deterministic state. 52 public final static String CUT_STACK_THREAD_NAME_REGEX = "Daemon|main"; 53 public final static Matcher CUT_STACK_THREADS = 54 Pattern.compile(CUT_STACK_THREAD_NAME_REGEX).matcher(""); 55 printAll(Object[][] stacks)56 public static void printAll(Object[][] stacks) { 57 List<String> stringified = new ArrayList<String>(stacks.length); 58 59 for (Object[] stackInfo : stacks) { 60 Thread t = (Thread)stackInfo[0]; 61 String name = (t != null) ? t.getName() : "null"; 62 String stackSerialization; 63 if (CUT_STACK_THREADS.reset(name).find()) { 64 // Do not print daemon stacks, as they're non-deterministic. 65 stackSerialization = "<not printed>"; 66 } else if (IGNORE_THREADS.reset(name).find()) { 67 // Skip IGNORE_THREADS. 68 continue; 69 } else { 70 StringBuilder sb = new StringBuilder(); 71 for (String[] stackElement : (String[][])stackInfo[1]) { 72 for (String part : stackElement) { 73 sb.append(' '); 74 sb.append(part); 75 } 76 sb.append('\n'); 77 } 78 stackSerialization = sb.toString(); 79 } 80 stringified.add(name + "\n" + stackSerialization); 81 } 82 83 Collections.sort(stringified); 84 85 for (String s : stringified) { 86 System.out.println("---------"); 87 System.out.println(s); 88 } 89 } 90 getStackTrace(Thread thread, int start, int max)91 public static native String[][] getStackTrace(Thread thread, int start, int max); 92 } 93