diff options
| author | 2017-07-27 23:27:32 +0000 | |
|---|---|---|
| committer | 2017-07-27 23:27:32 +0000 | |
| commit | 2e53f8f69f8c4175085e337445ec42aa045a2f7f (patch) | |
| tree | b6e4bfb0281138a3afd88c271f59ccef139d95bb /test/ti-agent/stack_trace_helper.cc | |
| parent | 60c29e42c2336cc6ef4f9acf157c211c7df83747 (diff) | |
| parent | 47d49b842a87823df6ffda30bb21bd6d8e4d8641 (diff) | |
Merge changes Iba7e9207,I11a4d3cb,I5a6746d3
* changes:
Tests for JVMTI can_access_local_variables functions
JVMTI set & get local variables
JVMTI GetLocalVariableTable function support
Diffstat (limited to 'test/ti-agent/stack_trace_helper.cc')
| -rw-r--r-- | test/ti-agent/stack_trace_helper.cc | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/test/ti-agent/stack_trace_helper.cc b/test/ti-agent/stack_trace_helper.cc new file mode 100644 index 0000000000..f2a8e9a318 --- /dev/null +++ b/test/ti-agent/stack_trace_helper.cc @@ -0,0 +1,99 @@ + +/* + * 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. + */ + +#include "common_helper.h" + +#include "jni.h" +#include "jvmti.h" + +#include "jvmti_helper.h" +#include "scoped_local_ref.h" +#include "test_env.h" + +namespace art { +namespace common_stack_trace { + +extern "C" JNIEXPORT jint JNICALL Java_art_StackTrace_GetStackDepth( + JNIEnv* env, jclass, jthread thr) { + jint ret; + JvmtiErrorToException(env, jvmti_env, jvmti_env->GetFrameCount(thr, &ret)); + return ret; +} + +extern "C" JNIEXPORT jobjectArray Java_art_StackTrace_nativeGetStackTrace(JNIEnv* env, + jclass, + jthread thr) { + jint depth; + ScopedLocalRef<jclass> klass(env, env->FindClass("art/StackTrace$StackFrameData")); + if (env->ExceptionCheck()) { + return nullptr; + } + jmethodID constructor = env->GetMethodID( + klass.get(), "<init>", "(Ljava/lang/Thread;Ljava/lang/reflect/Executable;JI)V"); + if (env->ExceptionCheck()) { + return nullptr; + } + if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetFrameCount(thr, &depth))) { + return nullptr; + } + // Just give some extra space. + depth += 10; + jvmtiFrameInfo* frames; + if (JvmtiErrorToException( + env, jvmti_env, jvmti_env->Allocate(depth * sizeof(jvmtiFrameInfo), + reinterpret_cast<unsigned char**>(&frames)))) { + return nullptr; + } + jint nframes = 0; + if (JvmtiErrorToException( + env, jvmti_env, jvmti_env->GetStackTrace(thr, 0, depth, frames, &nframes))) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return nullptr; + } + jobjectArray frames_array = env->NewObjectArray(nframes, klass.get(), nullptr); + if (env->ExceptionCheck()) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return nullptr; + } + for (jint i = 0; i < nframes; i++) { + jobject jmethod = GetJavaMethod(jvmti_env, env, frames[i].method); + if (env->ExceptionCheck()) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return nullptr; + } + jobject frame_obj = env->NewObject(klass.get(), + constructor, + thr, + jmethod, + frames[i].location, + i); + if (env->ExceptionCheck()) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return nullptr; + } + env->SetObjectArrayElement(frames_array, i, frame_obj); + if (env->ExceptionCheck()) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return nullptr; + } + } + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames)); + return frames_array; +} + +} // namespace common_stack_trace +} // namespace art |