Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  trace_helper.cc

  Sprache: C
 

/*
 * 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_trace {

static bool IsInCallback(JNIEnv* env, jvmtiEnv *jvmti, jthread thr) {
  void* data;
  ScopedLocalRef<jthrowable> exc(env, env->ExceptionOccurred());
  env->ExceptionClear();
  jvmti->GetThreadLocalStorage(thr, &data);
  if (exc.get() != nullptr) {
    env->Throw(exc.get());
  }
  if (data == nullptr) {
    return false;
  } else {
    return true;
  }
}

static void SetInCallback(JNIEnv* env, jvmtiEnv *jvmti, jthread thr, bool val) {
  ScopedLocalRef<jthrowable> exc(env, env->ExceptionOccurred());
  env->ExceptionClear();
  jvmti->SetThreadLocalStorage(thr, (val ? reinterpret_cast<void*>(0x1)
                                         : reinterpret_cast<void*>(0x0)));
  if (exc.get() != nullptr) {
    env->Throw(exc.get());
  }
}

class ScopedCallbackState {
 public:
  ScopedCallbackState(JNIEnv* jnienv, jvmtiEnv* env, jthread thr)
      : jnienv_(jnienv), env_(env), thr_(thr) {
    CHECK(!IsInCallback(jnienv_, env_, thr_));
    SetInCallback(jnienv_, env_, thr_, true);
  }
  ~ScopedCallbackState() {
    CHECK(IsInCallback(jnienv_, env_, thr_));
    SetInCallback(jnienv_, env_, thr_, false);
  }

 private:
  JNIEnv* jnienv_;
  jvmtiEnv* env_;
  jthread thr_;
};

struct TraceData {
  jclass test_klass;
  jmethodID enter_method;
  jmethodID exit_method;
  jmethodID field_access;
  jmethodID field_modify;
  jmethodID single_step;
  jmethodID thread_start;
  jmethodID thread_end;
  bool access_watch_on_load;
  bool modify_watch_on_load;
  jrawMonitorID trace_mon;

  jclass GetTestClass(jvmtiEnv* jvmti, JNIEnv* env) {
    if (JvmtiErrorToException(env, jvmti, jvmti->RawMonitorEnter(trace_mon))) {
      return nullptr;
    }
    jclass out = reinterpret_cast<jclass>(env->NewLocalRef(test_klass));
    if (JvmtiErrorToException(env, jvmti, jvmti->RawMonitorExit(trace_mon))) {
      return nullptr;
    }
    return out;
  }
};

static void threadStartCB(jvmtiEnv* jvmti,
                          JNIEnv* jnienv,
                          jthread thread) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->thread_start != nullptr);
  jnienv->CallStaticVoidMethod(klass.get(), data->thread_start, thread);
}
static void threadEndCB(jvmtiEnv* jvmti,
                          JNIEnv* jnienv,
                          jthread thread) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->thread_end != nullptr);
  jnienv->CallStaticVoidMethod(klass.get(), data->thread_end, thread);
}

static void singleStepCB(jvmtiEnv* jvmti,
                         JNIEnv* jnienv,
                         jthread thread,
                         jmethodID method,
                         jlocation location) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (IsInCallback(jnienv, jvmti, thread)) {
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->single_step != nullptr);
  ScopedCallbackState st(jnienv, jvmti, thread);
  jobject method_arg = GetJavaMethod(jvmti, jnienv, method);
  jnienv->CallStaticVoidMethod(klass.get(),
                               data->single_step,
                               thread,
                               method_arg,
                               static_cast<jlong>(location));
  jnienv->DeleteLocalRef(method_arg);
}

static void fieldAccessCB(jvmtiEnv* jvmti,
                          JNIEnv* jnienv,
                          jthread thr,
                          jmethodID method,
                          jlocation location,
                          jclass field_klass,
                          jobject object,
                          jfieldID field) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (IsInCallback(jnienv, jvmti, thr)) {
    // Don't do callback for either of these to prevent an infinite loop.
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->field_access != nullptr);
  ScopedCallbackState st(jnienv, jvmti, thr);
  jobject method_arg = GetJavaMethod(jvmti, jnienv, method);
  jobject field_arg = GetJavaField(jvmti, jnienv, field_klass, field);
  jnienv->CallStaticVoidMethod(klass.get(),
                               data->field_access,
                               method_arg,
                               static_cast<jlong>(location),
                               field_klass,
                               object,
                               field_arg);
  jnienv->DeleteLocalRef(method_arg);
  jnienv->DeleteLocalRef(field_arg);
}

static void fieldModificationCB(jvmtiEnv* jvmti,
                                JNIEnv* jnienv,
                                jthread thr,
                                jmethodID method,
                                jlocation location,
                                jclass field_klass,
                                jobject object,
                                jfieldID field,
                                char type_char,
                                jvalue new_value) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (IsInCallback(jnienv, jvmti, thr)) {
    // Don't do callback recursively to prevent an infinite loop.
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->field_modify != nullptr);
  ScopedCallbackState st(jnienv, jvmti, thr);
  jobject method_arg = GetJavaMethod(jvmti, jnienv, method);
  jobject field_arg = GetJavaField(jvmti, jnienv, field_klass, field);
  jobject value = GetJavaValueByType(jnienv, type_char, new_value);
  if (jnienv->ExceptionCheck()) {
    jnienv->DeleteLocalRef(method_arg);
    jnienv->DeleteLocalRef(field_arg);
    return;
  }
  jnienv->CallStaticVoidMethod(klass.get(),
                               data->field_modify,
                               method_arg,
                               static_cast<jlong>(location),
                               field_klass,
                               object,
                               field_arg,
                               value);
  jnienv->DeleteLocalRef(method_arg);
  jnienv->DeleteLocalRef(field_arg);
}

static void methodExitCB(jvmtiEnv* jvmti,
                         JNIEnv* jnienv,
                         jthread thr,
                         jmethodID method,
                         jboolean was_popped_by_exception,
                         jvalue return_value) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (method == data->exit_method ||
      method == data->enter_method ||
      IsInCallback(jnienv, jvmti, thr)) {
    // Don't do callback for either of these to prevent an infinite loop.
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  CHECK(data->exit_method != nullptr);
  ScopedCallbackState st(jnienv, jvmti, thr);
  jobject method_arg = GetJavaMethod(jvmti, jnienv, method);
  jobject result =
      was_popped_by_exception ? nullptr : GetJavaValue(jvmti, jnienv, method, return_value);
  if (jnienv->ExceptionCheck()) {
    return;
  }
  jnienv->CallStaticVoidMethod(klass.get(),
                               data->exit_method,
                               method_arg,
                               was_popped_by_exception,
                               result);
  jnienv->DeleteLocalRef(method_arg);
}

static void methodEntryCB(jvmtiEnv* jvmti,
                          JNIEnv* jnienv,
                          jthread thr,
                          jmethodID method) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  CHECK(data->enter_method != nullptr);
  if (method == data->exit_method ||
      method == data->enter_method ||
      IsInCallback(jnienv, jvmti, thr)) {
    // Don't do callback for either of these to prevent an infinite loop.
    return;
  }
  ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv));
  if (klass.get() == nullptr) {
    return;
  }
  ScopedCallbackState st(jnienv, jvmti, thr);
  jobject method_arg = GetJavaMethod(jvmti, jnienv, method);
  if (jnienv->ExceptionCheck()) {
    return;
  }
  jnienv->CallStaticVoidMethod(klass.get(), data->enter_method, method_arg);
  jnienv->DeleteLocalRef(method_arg);
}

static void classPrepareCB(jvmtiEnv* jvmti,
                           JNIEnv* jnienv,
                           [[maybe_unused]] jthread thr,
                           jclass klass) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(jnienv, jvmti,
                            jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  if (data->access_watch_on_load || data->modify_watch_on_load) {
    jint nfields;
    jfieldID* fields;
    if (JvmtiErrorToException(jnienv, jvmti, jvmti->GetClassFields(klass, &nfields, &fields))) {
      return;
    }
    for (jint i = 0; i < nfields; i++) {
      jfieldID f = fields[i];
      // Ignore errors
      if (data->access_watch_on_load) {
        jvmti->SetFieldAccessWatch(klass, f);
      }

      if (data->modify_watch_on_load) {
        jvmti->SetFieldModificationWatch(klass, f);
      }
    }
    jvmti->Deallocate(reinterpret_cast<unsigned char*>(fields));
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_watchAllFieldAccesses(JNIEnv* env) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(
      env, jvmti_env, jvmti_env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  data->access_watch_on_load = true;
  // We need the classPrepareCB to watch new fields as the classes are loaded/prepared.
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_CLASS_PREPARE,
                                                                nullptr))) {
    return;
  }
  jint nklasses;
  jclass* klasses;
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLoadedClasses(&nklasses, &klasses))) {
    return;
  }
  for (jint i = 0; i < nklasses; i++) {
    jclass k = klasses[i];

    jint nfields;
    jfieldID* fields;
    jvmtiError err = jvmti_env->GetClassFields(k, &nfields, &fields);
    if (err == JVMTI_ERROR_CLASS_NOT_PREPARED) {
      continue;
    } else if (JvmtiErrorToException(env, jvmti_env, err)) {
      jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(klasses));
      return;
    }
    for (jint j = 0; j < nfields; j++) {
      jvmti_env->SetFieldAccessWatch(k, fields[j]);
    }
    jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(fields));
  }
  jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(klasses));
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_watchAllFieldModifications(JNIEnv* env) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(
      env, jvmti_env, jvmti_env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  data->modify_watch_on_load = true;
  // We need the classPrepareCB to watch new fields as the classes are loaded/prepared.
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_CLASS_PREPARE,
                                                                nullptr))) {
    return;
  }
  jint nklasses;
  jclass* klasses;
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetLoadedClasses(&nklasses, &klasses))) {
    return;
  }
  for (jint i = 0; i < nklasses; i++) {
    jclass k = klasses[i];

    jint nfields;
    jfieldID* fields;
    jvmtiError err = jvmti_env->GetClassFields(k, &nfields, &fields);
    if (err == JVMTI_ERROR_CLASS_NOT_PREPARED) {
      continue;
    } else if (JvmtiErrorToException(env, jvmti_env, err)) {
      jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(klasses));
      return;
    }
    for (jint j = 0; j < nfields; j++) {
      jvmti_env->SetFieldModificationWatch(k, fields[j]);
    }
    jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(fields));
  }
  jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(klasses));
}

static bool GetFieldAndClass(JNIEnv* env,
                             jobject ref_field,
                             jclass* out_klass,
                             jfieldID* out_field) {
  *out_field = env->FromReflectedField(ref_field);
  if (env->ExceptionCheck()) {
    return false;
  }
  jclass field_klass = env->FindClass("java/lang/reflect/Field");
  if (env->ExceptionCheck()) {
    return false;
  }
  jmethodID get_declaring_class_method =
      env->GetMethodID(field_klass, "getDeclaringClass""()Ljava/lang/Class;");
  if (env->ExceptionCheck()) {
    env->DeleteLocalRef(field_klass);
    return false;
  }
  *out_klass = static_cast<jclass>(env->CallObjectMethod(ref_field, get_declaring_class_method));
  if (env->ExceptionCheck()) {
    *out_klass = nullptr;
    env->DeleteLocalRef(field_klass);
    return false;
  }
  env->DeleteLocalRef(field_klass);
  return true;
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_watchFieldModification(
    JNIEnv* env,
    [[maybe_unused]] jclass trace,
    jobject field_obj) {
  jfieldID field;
  jclass klass;
  if (!GetFieldAndClass(env, field_obj, &klass, &field)) {
    return;
  }

  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetFieldModificationWatch(klass, field));
  env->DeleteLocalRef(klass);
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_watchFieldAccess(
    JNIEnv* env,
    [[maybe_unused]] jclass trace,
    jobject field_obj) {
  jfieldID field;
  jclass klass;
  if (!GetFieldAndClass(env, field_obj, &klass, &field)) {
    return;
  }
  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetFieldAccessWatch(klass, field));
  env->DeleteLocalRef(klass);
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_nativeEnableFramePopEvents(JNIEnv* env) {
  jvmtiCapabilities caps;
  memset(&caps, 0sizeof(caps));
  caps.can_pop_frame = 1;
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps))) {
    return;
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing2(
    JNIEnv* env,
    [[maybe_unused]] jclass trace,
    jclass klass,
    jobject enter,
    jobject exit,
    jobject field_access,
    jobject field_modify,
    jobject single_step,
    jobject thread_start,
    jobject thread_end,
    jthread thr) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->Allocate(sizeof(TraceData),
                                                reinterpret_cast<unsigned char**>(&data)))) {
    return;
  }
  memset(data, 0sizeof(TraceData));
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->CreateRawMonitor("Trace monitor", &data->trace_mon))) {
    return;
  }
  data->test_klass = reinterpret_cast<jclass>(env->NewGlobalRef(klass));
  data->enter_method = enter != nullptr ? env->FromReflectedMethod(enter) : nullptr;
  data->exit_method = exit != nullptr ? env->FromReflectedMethod(exit) : nullptr;
  data->field_access = field_access != nullptr ? env->FromReflectedMethod(field_access) : nullptr;
  data->field_modify = field_modify != nullptr ? env->FromReflectedMethod(field_modify) : nullptr;
  data->single_step = single_step != nullptr ? env->FromReflectedMethod(single_step) : nullptr;
  data->thread_start = thread_start != nullptr ? env->FromReflectedMethod(thread_start) : nullptr;
  data->thread_end = thread_end != nullptr ? env->FromReflectedMethod(thread_end) : nullptr;

  TraceData* old_data = nullptr;
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->GetEnvironmentLocalStorage(
                                reinterpret_cast<void**>(&old_data)))) {
    return;
  } else if (old_data != nullptr && old_data->test_klass != nullptr) {
    ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
    env->ThrowNew(rt_exception.get(), "Environment already has local storage set!");
    return;
  }
  if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEnvironmentLocalStorage(data))) {
    return;
  }

  current_callbacks.MethodEntry = methodEntryCB;
  current_callbacks.MethodExit = methodExitCB;
  current_callbacks.FieldAccess = fieldAccessCB;
  current_callbacks.FieldModification = fieldModificationCB;
  current_callbacks.ClassPrepare = classPrepareCB;
  current_callbacks.SingleStep = singleStepCB;
  current_callbacks.ThreadStart = threadStartCB;
  current_callbacks.ThreadEnd = threadEndCB;
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventCallbacks(¤t_callbacks,
                                                         sizeof(current_callbacks)))) {
    return;
  }
  if (enter != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_METHOD_ENTRY,
                                                                thr))) {
    return;
  }
  if (exit != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_METHOD_EXIT,
                                                                thr))) {
    return;
  }
  if (field_access != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_FIELD_ACCESS,
                                                                thr))) {
    return;
  }
  if (field_modify != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_FIELD_MODIFICATION,
                                                                thr))) {
    return;
  }
  if (single_step != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_SINGLE_STEP,
                                                                thr))) {
    return;
  }
  if (thread_start != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_THREAD_START,
                                                                thr))) {
    return;
  }
  if (thread_end != nullptr &&
      JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
                                                                JVMTI_EVENT_THREAD_END,
                                                                thr))) {
    return;
  }
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing(
    JNIEnv* env,
    jclass trace,
    jclass klass,
    jobject enter,
    jobject exit,
    jobject field_access,
    jobject field_modify,
    jobject single_step,
    jthread thr) {
  Java_art_Trace_enableTracing2(env,
                                trace,
                                klass,
                                enter,
                                exit,
                                field_access,
                                field_modify,
                                single_step,
                                /* thread_start */ nullptr,
                                /* thread_end */ nullptr,
                                thr);
  return;
}

extern "C" JNIEXPORT void JNICALL Java_art_Trace_disableTracing(
    JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
  TraceData* data = nullptr;
  if (JvmtiErrorToException(
      env, jvmti_env, jvmti_env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) {
    return;
  }
  // If data is null then we haven't ever enabled tracing so we don't need to do anything.
  if (data == nullptr || data->test_klass == nullptr) {
    return;
  }
  ScopedLocalRef<jthrowable> err(env, nullptr);
  // First disable all the events.
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
                                                                JVMTI_EVENT_FIELD_ACCESS,
                                                                thr))) {
    env->ExceptionDescribe();
    err.reset(env->ExceptionOccurred());
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
                                                                JVMTI_EVENT_FIELD_MODIFICATION,
                                                                thr))) {
    env->ExceptionDescribe();
    err.reset(env->ExceptionOccurred());
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
                                                                JVMTI_EVENT_METHOD_ENTRY,
                                                                thr))) {
    env->ExceptionDescribe();
    err.reset(env->ExceptionOccurred());
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
                                                                JVMTI_EVENT_METHOD_EXIT,
                                                                thr))) {
    env->ExceptionDescribe();
    err.reset(env->ExceptionOccurred());
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
                                                                JVMTI_EVENT_SINGLE_STEP,
                                                                thr))) {
    env->ExceptionDescribe();
    err.reset(env->ExceptionOccurred());
    env->ExceptionClear();
  }
  if (JvmtiErrorToException(env, jvmti_env,
                            jvmti_env->RawMonitorEnter(data->trace_mon))) {
    return;
  }
  // Clear test_klass so we know this isn't being used
  env->DeleteGlobalRef(data->test_klass);
  data->test_klass = nullptr;
  if (JvmtiErrorToException(env,
                            jvmti_env,
                            jvmti_env->RawMonitorExit(data->trace_mon))) {
    return;
  }
  if (err.get() != nullptr) {
    env->Throw(err.get());
  }
}

}  // namespace common_trace


}  // namespace art

Messung V0.5 in Prozent
C=90 H=89 G=89

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik