1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dalvik.system.VMStack
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
21db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro#include "UniquePtr.h"
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "native/InternalNativePriv.h"
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public static ClassLoader getCallingClassLoader()
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the defining class loader of the caller's caller.
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
3230bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee    ClassObject* clazz =
3330bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee        dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz == NULL)
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RETURN_PTR(NULL);
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_PTR(clazz->classLoader);
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
438210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson * public static Class<?> getStackClass2()
448210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson *
458210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson * Returns the class of the caller's caller's caller.
468210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson */
478210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilsonstatic void Dalvik_dalvik_system_VMStack_getStackClass2(const u4* args,
488210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson    JValue* pResult)
498210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson{
5030bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee    ClassObject* clazz =
5130bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee        dvmGetCaller3Class(dvmThreadSelf()->interpSave.curFrame);
528210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson
538210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson    UNUSED_PARAMETER(args);
548210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson
558210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson    RETURN_PTR(clazz);
568210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson}
578210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson
588210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson/*
59ec2a40a791625da91cb57a674e9f240af09455bdDan Bornstein * public static Class<?>[] getClasses(int maxDepth)
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an array of classes for the methods on the stack, skipping the
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * first two and all reflection methods.  If "stopAtPrivileged" is set,
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stop shortly after we encounter a privileged class.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMStack_getClasses(const u4* args,
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* note "maxSize" is unsigned, so -1 turns into a very large value */
69db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    size_t maxSize = args[0];
70db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    size_t size = 0;
71db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    const size_t kSkip = 2;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Get an array with the stack trace in it.
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
7630bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee    void *fp = dvmThreadSelf()->interpSave.curFrame;
77db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    size_t depth = dvmComputeExactFrameDepth(fp);
78db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    UniquePtr<const Method*[]> methods(new const Method*[depth]);
79db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    dvmFillStackTraceArray(fp, methods.get(), depth);
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Run through the array and count up how many elements there are.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
84db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    for (size_t i = kSkip; i < depth && size < maxSize; ++i) {
85db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        const Method* meth = methods[i];
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsReflectionMethod(meth))
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size++;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Create an array object to hold the classes.
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: can use gDvm.classJavaLangClassArray here?
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
97db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    ClassObject* classArrayClass = dvmFindArrayClass("[Ljava/lang/Class;",
98db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro                                                     NULL);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (classArrayClass == NULL) {
100e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block        ALOGW("Unable to find java.lang.Class array class");
101db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        return;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
103d52d4b1e08009c57f1fdc6e13b90cb8948a60102Carl Shapiro    ArrayObject* classes = dvmAllocArrayByClass(classArrayClass,
104d52d4b1e08009c57f1fdc6e13b90cb8948a60102Carl Shapiro                                                size,
105d52d4b1e08009c57f1fdc6e13b90cb8948a60102Carl Shapiro                                                ALLOC_DEFAULT);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (classes == NULL) {
107e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block        ALOGW("Unable to allocate class array of %zd elements", size);
108db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        return;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Fill in the array.
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
114db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    size_t objCount = 0;
115db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    for (size_t i = kSkip; i < depth; ++i) {
116db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        if (dvmIsReflectionMethod(methods[i])) {
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            continue;
118364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        }
119db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        Object* klass = (Object *)methods[i]->clazz;
120db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro        dvmSetObjectArrayElement(classes, objCount, klass);
121364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        objCount++;
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
123364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes    assert(objCount == classes->length);
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125db0c9549818d9f6e508d26e45ff9d886802aa1daCarl Shapiro    dvmReleaseTrackedAlloc((Object*)classes, NULL);
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_PTR(classes);
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1306b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * Return a trace buffer for the specified thread or NULL if the
1316b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * thread is not still alive. *depth is set to the length of a
1326b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * non-NULL trace buffer. Caller is responsible for freeing the trace
1336b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * buffer.
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1356b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstromstatic int* getTraceBuf(Object* targetThreadObj, size_t* pStackDepth)
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* thread;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int* traceBuf;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(targetThreadObj != NULL);
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmLockThreadList(self);
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Make sure the thread is still alive and in the list.
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thread->threadObj == targetThreadObj)
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            break;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread == NULL) {
1534308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block        ALOGI("VMStack.getTraceBuf: threadObj %p not active",
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            targetThreadObj);
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmUnlockThreadList();
1566b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom        return NULL;
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Suspend the thread, pull out the stack trace, then resume the thread
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and release the thread list lock.  If we're being asked to examine
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * our own stack trace, skip the suspend/resume.
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != self)
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSuspendThread(thread);
1666b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    traceBuf = dvmFillInStackTraceRaw(thread, pStackDepth);
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (thread != self)
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmResumeThread(thread);
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmUnlockThreadList();
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1716b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    return traceBuf;
1726b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom}
1736b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
1746b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom/*
1756b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * public static StackTraceElement[] getThreadStackTrace(Thread t)
1766b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom *
1776b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * Retrieve the stack trace of the specified thread and return it as an
1786b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * array of StackTraceElement.  Returns NULL on failure.
1796b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom */
1806b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstromstatic void Dalvik_dalvik_system_VMStack_getThreadStackTrace(const u4* args,
1816b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    JValue* pResult)
1826b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom{
1836b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    Object* targetThreadObj = (Object*) args[0];
1846b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    size_t stackDepth;
1856b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    int* traceBuf = getTraceBuf(targetThreadObj, &stackDepth);
1866b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
1876b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    if (traceBuf == NULL)
1886b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom        RETURN_PTR(NULL);
1896b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Convert the raw buffer into an array of StackTraceElement.
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* trace = dvmGetStackTraceRaw(traceBuf, stackDepth);
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(traceBuf);
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_PTR(trace);
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1986b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom/*
1996b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * public static int fillStackTraceElements(Thread t, StackTraceElement[] stackTraceElements)
2006b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom *
2016b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * Retrieve a partial stack trace of the specified thread and return
2026b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom * the number of frames filled.  Returns 0 on failure.
2036b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom */
2046b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstromstatic void Dalvik_dalvik_system_VMStack_fillStackTraceElements(const u4* args,
2056b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    JValue* pResult)
2066b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom{
2076b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    Object* targetThreadObj = (Object*) args[0];
2086b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    ArrayObject* steArray = (ArrayObject*) args[1];
2096b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    size_t stackDepth;
2106b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    int* traceBuf = getTraceBuf(targetThreadObj, &stackDepth);
2116b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
2126b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    if (traceBuf == NULL)
2136b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom        RETURN_PTR(NULL);
2146b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
2156b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    /*
2166b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom     * Set the raw buffer into an array of StackTraceElement.
2176b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom     */
2186b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    if (stackDepth > steArray->length) {
2196b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom        stackDepth = steArray->length;
2206b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    }
2216b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    dvmFillStackTraceElements(traceBuf, stackDepth, steArray);
2226b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    free(traceBuf);
2236b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    RETURN_INT(stackDepth);
2246b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom}
2256b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst DalvikNativeMethod dvm_dalvik_system_VMStack[] = {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "getCallingClassLoader",  "()Ljava/lang/ClassLoader;",
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMStack_getCallingClassLoader },
2296b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    { "getStackClass2",         "()Ljava/lang/Class;",
2308210fadf25ece2a0db4cd0428d7f27d7166310b9Jesse Wilson        Dalvik_dalvik_system_VMStack_getStackClass2 },
231ec2a40a791625da91cb57a674e9f240af09455bdDan Bornstein    { "getClasses",             "(I)[Ljava/lang/Class;",
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMStack_getClasses },
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "getThreadStackTrace",    "(Ljava/lang/Thread;)[Ljava/lang/StackTraceElement;",
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMStack_getThreadStackTrace },
2356b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom    { "fillStackTraceElements", "(Ljava/lang/Thread;[Ljava/lang/StackTraceElement;)I",
2366b1f9f877b70fcc5375fa33a445ac84777757eb2Brian Carlstrom        Dalvik_dalvik_system_VMStack_fillStackTraceElements },
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { NULL, NULL, NULL },
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
239