| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package art; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Executable; |
| |
| public class StackTrace { |
| public static class StackFrameData { |
| public final Thread thr; |
| public final Executable method; |
| public final long current_location; |
| public final int depth; |
| |
| public StackFrameData(Thread thr, Executable e, long loc, int depth) { |
| this.thr = thr; |
| this.method = e; |
| this.current_location = loc; |
| this.depth = depth; |
| } |
| @Override |
| public String toString() { |
| return String.format( |
| "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }", |
| this.thr, |
| this.method, |
| this.current_location, |
| this.depth); |
| } |
| } |
| |
| public static native int GetStackDepth(Thread thr); |
| |
| private static native StackFrameData[] nativeGetStackTrace(Thread thr); |
| |
| public static StackFrameData[] GetStackTrace(Thread thr) { |
| // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not |
| // suspended. The spec says that not being suspended is fine but since we want this to be |
| // consistent we will suspend for the RI. |
| boolean suspend_thread = |
| !System.getProperty("java.vm.name").equals("Dalvik") && |
| !thr.equals(Thread.currentThread()); |
| if (suspend_thread) { |
| Suspension.suspend(thr); |
| } |
| StackFrameData[] out = nativeGetStackTrace(thr); |
| if (suspend_thread) { |
| Suspension.resume(thr); |
| } |
| return out; |
| } |
| } |
| |