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