Home | History | Annotate | Download | only in ti-agent
      1 
      2 /*
      3  * Copyright (C) 2017 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include "common_helper.h"
     19 
     20 #include "jni.h"
     21 #include "jvmti.h"
     22 
     23 #include "jvmti_helper.h"
     24 #include "scoped_local_ref.h"
     25 #include "test_env.h"
     26 
     27 namespace art {
     28 namespace common_stack_trace {
     29 
     30 extern "C" JNIEXPORT jint JNICALL Java_art_StackTrace_GetStackDepth(
     31     JNIEnv* env, jclass, jthread thr) {
     32   jint ret;
     33   JvmtiErrorToException(env, jvmti_env, jvmti_env->GetFrameCount(thr, &ret));
     34   return ret;
     35 }
     36 
     37 extern "C" JNIEXPORT jobjectArray Java_art_StackTrace_nativeGetStackTrace(JNIEnv* env,
     38                                                                           jclass,
     39                                                                           jthread thr) {
     40   jint depth;
     41   ScopedLocalRef<jclass> klass(env, env->FindClass("art/StackTrace$StackFrameData"));
     42   if (env->ExceptionCheck()) {
     43     return nullptr;
     44   }
     45   jmethodID constructor = env->GetMethodID(
     46       klass.get(), "<init>", "(Ljava/lang/Thread;Ljava/lang/reflect/Executable;JI)V");
     47   if (env->ExceptionCheck()) {
     48     return nullptr;
     49   }
     50   if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetFrameCount(thr, &depth))) {
     51     return nullptr;
     52   }
     53   // Just give some extra space.
     54   depth += 10;
     55   jvmtiFrameInfo* frames;
     56   if (JvmtiErrorToException(
     57       env, jvmti_env, jvmti_env->Allocate(depth * sizeof(jvmtiFrameInfo),
     58                                           reinterpret_cast<unsigned char**>(&frames)))) {
     59     return nullptr;
     60   }
     61   jint nframes = 0;
     62   if (JvmtiErrorToException(
     63       env, jvmti_env, jvmti_env->GetStackTrace(thr, 0, depth, frames, &nframes))) {
     64     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     65     return nullptr;
     66   }
     67   jobjectArray frames_array = env->NewObjectArray(nframes, klass.get(), nullptr);
     68   if (env->ExceptionCheck()) {
     69     jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     70     return nullptr;
     71   }
     72   for (jint i = 0; i < nframes; i++) {
     73     jobject jmethod = GetJavaMethod(jvmti_env, env, frames[i].method);
     74     if (env->ExceptionCheck()) {
     75       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     76       return nullptr;
     77     }
     78     jobject frame_obj = env->NewObject(klass.get(),
     79                                        constructor,
     80                                        thr,
     81                                        jmethod,
     82                                        frames[i].location,
     83                                        i);
     84     if (env->ExceptionCheck()) {
     85       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     86       return nullptr;
     87     }
     88     env->SetObjectArrayElement(frames_array, i, frame_obj);
     89     if (env->ExceptionCheck()) {
     90       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     91       return nullptr;
     92     }
     93   }
     94   jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(frames));
     95   return frames_array;
     96 }
     97 
     98 }  // namespace common_stack_trace
     99 }  // namespace art
    100