1e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light/* 2e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * Copyright (C) 2017 The Android Open Source Project 3e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * 4e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * Licensed under the Apache License, Version 2.0 (the "License"); 5e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * you may not use this file except in compliance with the License. 6e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * You may obtain a copy of the License at 7e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * 8e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * http://www.apache.org/licenses/LICENSE-2.0 9e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * 10e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * Unless required by applicable law or agreed to in writing, software 11e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * distributed under the License is distributed on an "AS IS" BASIS, 12e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * See the License for the specific language governing permissions and 14e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light * limitations under the License. 15e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light */ 16e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 17e814f9d09c0fb1b678e610780d11ce3577db3599Alex Lightpackage art; 18e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 19e814f9d09c0fb1b678e610780d11ce3577db3599Alex Lightimport java.lang.reflect.Field; 20e814f9d09c0fb1b678e610780d11ce3577db3599Alex Lightimport java.lang.reflect.Executable; 21e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 22e814f9d09c0fb1b678e610780d11ce3577db3599Alex Lightpublic class StackTrace { 23e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public static class StackFrameData { 24e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public final Thread thr; 25e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public final Executable method; 26e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public final long current_location; 27e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public final int depth; 28e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 29e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public StackFrameData(Thread thr, Executable e, long loc, int depth) { 30e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.thr = thr; 31e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.method = e; 32e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.current_location = loc; 33e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.depth = depth; 34e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 35e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light @Override 36e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public String toString() { 37e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light return String.format( 38e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }", 39e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.thr, 40e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.method, 41e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.current_location, 42e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light this.depth); 43e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 44e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 45e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 46e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public static native int GetStackDepth(Thread thr); 47e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 48e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light private static native StackFrameData[] nativeGetStackTrace(Thread thr); 49e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 50e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light public static StackFrameData[] GetStackTrace(Thread thr) { 51e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not 52e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light // suspended. The spec says that not being suspended is fine but since we want this to be 53e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light // consistent we will suspend for the RI. 54e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light boolean suspend_thread = 55e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light !System.getProperty("java.vm.name").equals("Dalvik") && 56e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light !thr.equals(Thread.currentThread()) && 57e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light !Suspension.isSuspended(thr); 58e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light if (suspend_thread) { 59e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light Suspension.suspend(thr); 60e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 61e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light StackFrameData[] out = nativeGetStackTrace(thr); 62e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light if (suspend_thread) { 63e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light Suspension.resume(thr); 64e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 65e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light return out; 66e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light } 67e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light} 68e814f9d09c0fb1b678e610780d11ce3577db3599Alex Light 69