products/Sources/formale Sprachen/JAVA/openjdk-20-36_src/test/lib/jdk/test/lib/jvmti image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: jvmti_common.h   Sprache: C

/*
 * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


#ifndef JVMTI_COMMON_H
#define JVMTI_COMMON_H

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "jvmti.h"

/**
 * Additional Java basic types
 */


#ifdef _WIN32
    typedef unsigned __int64 julong;
#else
    typedef unsigned long long julong;
#endif

#define LOG(...) \
  { \
    printf(__VA_ARGS__); \
    fflush(stdout); \
  }

#define COMPLAIN LOG


const char* TranslateState(jint flags);
const char* TranslateError(jvmtiError err);

static jvmtiExtensionFunction GetVirtualThread_func = NULL;
static jvmtiExtensionFunction GetCarrierThread_func = NULL;

/**
 * Convert the digits of the given value argument to a null-terminated
 * character string and store the result (up to 32 bytes) in string.
 * If value is negative, the first character of the stored string is
 * the minus sign (-). The function returns a pointer to the begining
 * of the result string.
 */

char* jlong_to_string(jlong value, char *string) {
  char buffer[32];
  char *pbuf, *pstr;

  pstr = string;
  if (value == 0) {
    *pstr++ = '0';
  } else {
    if (value < 0) {
      *pstr++ = '-';
      value = -value;
    }
    pbuf = buffer;
    while (value != 0) {
      *pbuf++ = '0' + (char)(value % 10);
      value = value / 10;
    }
    while (pbuf != buffer) {
      *pstr++ = *--pbuf;
    }
  }
  *pstr = '\0';

  return string;
}

/**
 * Convert the digits of the given value argument to a null-terminated
 * character string and store the result (up to 32 bytes) in string.
 * The function returns a pointer to the begining of the result string.
 */

char* julong_to_string(julong value, char *string) {
    char buffer[32];
    char *pbuf, *pstr;

    pstr = string;
    if (value == 0) {
        *pstr++ = '0';
    } else {
        pbuf = buffer;
        while (value != 0) {
            *pbuf++ = '0' + (char)(value % 10);
            value = value / 10;
        }
        while (pbuf != buffer) {
            *pstr++ = *--pbuf;
        }
    }
    *pstr = '\0';

    return string;
}

static void
fatal(JNIEnv* jni, const char* msg) {
  jni->FatalError(msg);
}


static void
check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) {
  if (err != JVMTI_ERROR_NONE) {
    LOG("check_jvmti_status: JVMTI function returned error: %s (%d)\n", TranslateError(err), err);
    jni->FatalError(msg);
  }
}

/* JVMTI helper wrappers. Check errors and fail or return null if jvmti operation failed. */

// Monitors often created in Agent_Initialize(..) where JNIEnv* jni doesn't exist.
jrawMonitorID
create_raw_monitor(jvmtiEnv *jvmti, const char* name) {
  jrawMonitorID lock;
  jvmtiError err = jvmti->CreateRawMonitor(name, &lock);
  if (err != JVMTI_ERROR_NONE) {
    return nullptr;
  }
  return lock;
}

void
destroy_raw_monitor(jvmtiEnv *jvmti, JNIEnv *jni, jrawMonitorID lock) {
  check_jvmti_status(jni, jvmti->DestroyRawMonitor(lock), "DestroyRawMonitor failed.");
}

class RawMonitorLocker {
 private:
  jvmtiEnv* _jvmti;
  JNIEnv* _jni;
  jrawMonitorID _monitor;

 public:
  RawMonitorLocker(jvmtiEnv *jvmti,JNIEnv* jni, jrawMonitorID monitor):_jvmti(jvmti), _jni(jni), _monitor(monitor) {
    check_jvmti_status(_jni, _jvmti->RawMonitorEnter(_monitor), "Fatal Error in RawMonitorEnter.");
  }

  ~RawMonitorLocker() {
    check_jvmti_status(_jni, _jvmti->RawMonitorExit(_monitor), "Fatal Error in RawMonitorEnter.");
  }

  void wait(jlong millis) {
    check_jvmti_status(_jni, _jvmti->RawMonitorWait(_monitor, millis), "Fatal Error in RawMonitorWait.");
  }

  void wait() {
    wait(0);
  }

  void notify() {
    check_jvmti_status(_jni, _jvmti->RawMonitorNotify(_monitor), "Fatal Error in RawMonitorNotify.");
  }

  void notify_all() {
    check_jvmti_status(_jni, _jvmti->RawMonitorNotifyAll(_monitor), "Fatal Error in RawMonitorNotifyAll.");
  }

};

static void
deallocate(jvmtiEnv *jvmti, JNIEnv* jni, void* ptr) {
  jvmtiError err = jvmti->Deallocate((unsigned char*)ptr);
  check_jvmti_status(jni, err, "deallocate: error in JVMTI Deallocate call");
}

static char*
get_method_class_name(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method) {
  jclass klass = NULL;
  char*  cname = NULL;
  char*  result = NULL;
  jvmtiError err;

  err = jvmti->GetMethodDeclaringClass(method, &klass);
  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetMethodDeclaringClass");

  err = jvmti->GetClassSignature(klass, &cname, NULL);
  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetClassSignature");

  size_t len = strlen(cname) - 2; // get rid of leading 'L' and trailing ';'

  err = jvmti->Allocate((jlong)(len + 1), (unsigned char**)&result);
  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI Allocate");

  strncpy(result, cname + 1, len); // skip leading 'L'
  result[len] = '\0';
  deallocate(jvmti, jni, (void*)cname);
  return result;
}


static void
print_method(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method, jint depth) {
  char*  cname = NULL;
  char*  mname = NULL;
  char*  msign = NULL;
  jvmtiError err;

  cname = get_method_class_name(jvmti, jni, method);

  err = jvmti->GetMethodName(method, &mname, &msign, NULL);
  check_jvmti_status(jni, err, "print_method: error in JVMTI GetMethodName");

  LOG("%2d: %s: %s%s\n", depth, cname, mname, msign);
  fflush(0);
  deallocate(jvmti, jni, (void*)cname);
  deallocate(jvmti, jni, (void*)mname);
  deallocate(jvmti, jni, (void*)msign);
}

void
print_thread_info(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread_obj) {
  jvmtiThreadInfo thread_info;
  jint thread_state;
  check_jvmti_status(jni, jvmti->GetThreadInfo(thread_obj, &thread_info), "Error in GetThreadInfo");
  check_jvmti_status(jni, jvmti->GetThreadState(thread_obj, &thread_state), "Error in GetThreadInfo");
  const char* state = TranslateState(thread_state);
  LOG("Thread: %p, name: %s, state(%x): %s, attrs: %s %s\n", thread_obj, thread_info.name, thread_state, TranslateState(thread_state),
         (jni->IsVirtualThread(thread_obj)? "virtual""kernel"), (thread_info.is_daemon ? "daemon"""));
}

static void
print_stack_trace_frames(jvmtiEnv *jvmti, JNIEnv *jni, jint count, jvmtiFrameInfo *frames) {
  LOG("JVMTI Stack Trace: frame count: %d\n", count);
  for (int depth = 0; depth < count; depth++) {
    print_method(jvmti, jni, frames[depth].method, depth);
  }
  LOG("\n");
}

static jint
get_frame_count(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  jint frame_count;
  jvmtiError err = jvmti->GetFrameCount(thread, &frame_count);
  check_jvmti_status(jni, err, "get_frame_count: error in JVMTI GetFrameCount call");
  return frame_count;
}

static jvmtiThreadInfo
get_thread_info(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  jvmtiThreadInfo thr_info;
  jvmtiError err = jvmti->GetThreadInfo(thread, &thr_info);
  check_jvmti_status(jni, err, "get_thread_info: error in JVMTI GetThreadInfo call");
  return thr_info;
}

static jint
get_thread_state(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  jint thread_state;
  jvmtiError err = jvmti->GetThreadState(thread, &thread_state);
  check_jvmti_status(jni, err, "get_thread_state: error in JVMTI GetThreadState call");
  return thread_state;
}

static char*
get_thread_name(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  jvmtiThreadInfo thr_info;
  jvmtiError err;

  memset(&thr_info, 0, sizeof(thr_info));
  err = jvmti->GetThreadInfo(thread, &thr_info);
  if (err == JVMTI_ERROR_WRONG_PHASE || err == JVMTI_ERROR_THREAD_NOT_ALIVE) {
    return NULL; // VM or target thread completed its work
  }
  check_jvmti_status(jni, err, "get_thread_name: error in JVMTI GetThreadInfo call");

  static const char* UNNAMED_STR = "";
  static size_t UNNAMED_LEN = strlen(UNNAMED_STR);
  char* tname = thr_info.name;
  if (tname == NULL) {
    err = jvmti->Allocate((jlong)(UNNAMED_LEN + 1), (unsigned char**)&tname);
    check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI Allocate");
    strncpy(tname, UNNAMED_STR, UNNAMED_LEN);
    tname[UNNAMED_LEN] = '\0';
  }
  return tname;
}

static char*
get_method_name(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method) {
  char*  mname = NULL;
  jvmtiError err;

  err = jvmti->GetMethodName(method, &mname, NULL, NULL);
  check_jvmti_status(jni, err, "get_method_name: error in JVMTI GetMethodName call");

  return mname;
}

static jclass
find_class(jvmtiEnv *jvmti, JNIEnv *jni, jobject loader, const char* cname) {
  jclass *classes = NULL;
  jint count = 0;
  jvmtiError err;

  err = jvmti->GetClassLoaderClasses(loader, &count, &classes);
  check_jvmti_status(jni, err, "find_class: error in JVMTI GetClassLoaderClasses");

  // Find the jmethodID of the specified method
  while (--count >= 0) {
    char* name = NULL;
    jclass klass = classes[count];

    err = jvmti->GetClassSignature(klass, &name, NULL);
    check_jvmti_status(jni, err, "find_class: error in JVMTI GetClassSignature call");

    bool found = (strcmp(name, cname) == 0);
    deallocate(jvmti, jni, (void*)name);
    if (found) {
      return klass;
    }
  }
  return NULL;
}

static jmethodID
find_method(jvmtiEnv *jvmti, JNIEnv *jni, jclass klass, const char* mname) {
  jmethodID *methods = NULL;
  jmethodID method = NULL;
  jint count = 0;
  jvmtiError err;

  err = jvmti->GetClassMethods(klass, &count, &methods);
  check_jvmti_status(jni, err, "find_method: error in JVMTI GetClassMethods");

  // Find the jmethodID of the specified method
  while (--count >= 0) {
    char* name = NULL;

    jmethodID meth = methods[count];

    err = jvmti->GetMethodName(meth, &name, NULL, NULL);
    check_jvmti_status(jni, err, "find_method: error in JVMTI GetMethodName call");

    bool found = (strcmp(name, mname) == 0);
    deallocate(jvmti, jni, (void*)name);
    if (found) {
      method = meth;
      break;
    }
  }
  deallocate(jvmti, jni, (void*)methods);
  return method;
}

#define MAX_FRAME_COUNT_PRINT_STACK_TRACE 200

static void
print_current_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni) {
  jvmtiFrameInfo frames[MAX_FRAME_COUNT_PRINT_STACK_TRACE];
  jint count = 0;

  jvmtiError err = jvmti->GetStackTrace(NULL, 0, MAX_FRAME_COUNT_PRINT_STACK_TRACE, frames, &count);
  check_jvmti_status(jni, err, "print_stack_trace: error in JVMTI GetStackTrace");

  LOG("JVMTI Stack Trace for current thread: frame count: %d\n", count);
  for (int depth = 0; depth < count; depth++) {
    print_method(jvmti, jni, frames[depth].method, depth);
  }
  LOG("\n");
}

static void
print_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  jvmtiFrameInfo frames[MAX_FRAME_COUNT_PRINT_STACK_TRACE];
  char* tname = get_thread_name(jvmti, jni, thread);
  jint count = 0;

  jvmtiError err = jvmti->GetStackTrace(thread, 0, MAX_FRAME_COUNT_PRINT_STACK_TRACE, frames, &count);
  check_jvmti_status(jni, err, "print_stack_trace: error in JVMTI GetStackTrace");

  LOG("JVMTI Stack Trace for thread %s: frame count: %d\n", tname, count);
  for (int depth = 0; depth < count; depth++) {
    print_method(jvmti, jni, frames[depth].method, depth);
  }
  deallocate(jvmti, jni, (void*)tname);
  LOG("\n");
}


static void suspend_thread(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  check_jvmti_status(jni, jvmti->SuspendThread(thread), "error in JVMTI SuspendThread");
}

static void resume_thread(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
  check_jvmti_status(jni, jvmti->ResumeThread(thread), "error in JVMTI ResumeThread");
}

static jthread get_current_thread(jvmtiEnv *jvmti, JNIEnv* jni) {
  jthread thread;
  check_jvmti_status(jni, jvmti->GetCurrentThread(&thread), "error in JVMTI GetCurrentThread");
  return thread;
}



/* Commonly used helper functions */
const char*
TranslateState(jint flags) {
  static char str[15 * 20];

  if (flags == 0) {
    return "";
  }
  str[0] = '\0';

  if (flags & JVMTI_THREAD_STATE_ALIVE) {
    strcat(str, " ALIVE");
  }
  if (flags & JVMTI_THREAD_STATE_TERMINATED) {
    strcat(str, " TERMINATED");
  }
  if (flags & JVMTI_THREAD_STATE_RUNNABLE) {
    strcat(str, " RUNNABLE");
  }
  if (flags & JVMTI_THREAD_STATE_WAITING) {
    strcat(str, " WAITING");
  }
  if (flags & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) {
    strcat(str, " WAITING_INDEFINITELY");
  }
  if (flags & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) {
    strcat(str, " WAITING_WITH_TIMEOUT");
  }
  if (flags & JVMTI_THREAD_STATE_SLEEPING) {
    strcat(str, " SLEEPING");
  }
  if (flags & JVMTI_THREAD_STATE_IN_OBJECT_WAIT) {
    strcat(str, " IN_OBJECT_WAIT");
  }
  if (flags & JVMTI_THREAD_STATE_PARKED) {
    strcat(str, " PARKED");
  }
  if (flags & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) {
    strcat(str, " BLOCKED_ON_MONITOR_ENTER");
  }
  if (flags & JVMTI_THREAD_STATE_SUSPENDED) {
    strcat(str, " SUSPENDED");
  }
  if (flags & JVMTI_THREAD_STATE_INTERRUPTED) {
    strcat(str, " INTERRUPTED");
  }
  if (flags & JVMTI_THREAD_STATE_IN_NATIVE) {
    strcat(str, " IN_NATIVE");
  }
  return str;
}

const char*
TranslateEvent(jvmtiEvent event_type) {
    switch (event_type) {
    case JVMTI_EVENT_VM_INIT:
        return ("JVMTI_EVENT_VM_INIT");
    case JVMTI_EVENT_VM_DEATH:
        return ("JVMTI_EVENT_VM_DEATH");
    case JVMTI_EVENT_THREAD_START:
        return ("JVMTI_EVENT_THREAD_START");
    case JVMTI_EVENT_THREAD_END:
        return ("JVMTI_EVENT_THREAD_END");
    case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
        return ("JVMTI_EVENT_CLASS_FILE_LOAD_HOOK");
    case JVMTI_EVENT_CLASS_LOAD:
        return ("JVMTI_EVENT_CLASS_LOAD");
    case JVMTI_EVENT_CLASS_PREPARE:
        return ("JVMTI_EVENT_CLASS_PREPARE");
    case JVMTI_EVENT_VM_START:
        return ("JVMTI_EVENT_VM_START");
    case JVMTI_EVENT_EXCEPTION:
        return ("JVMTI_EVENT_EXCEPTION");
    case JVMTI_EVENT_EXCEPTION_CATCH:
        return ("JVMTI_EVENT_EXCEPTION_CATCH");
    case JVMTI_EVENT_SINGLE_STEP:
        return ("JVMTI_EVENT_SINGLE_STEP");
    case JVMTI_EVENT_FRAME_POP:
        return ("JVMTI_EVENT_FRAME_POP");
    case JVMTI_EVENT_BREAKPOINT:
        return ("JVMTI_EVENT_BREAKPOINT");
    case JVMTI_EVENT_FIELD_ACCESS:
        return ("JVMTI_EVENT_FIELD_ACCESS");
    case JVMTI_EVENT_FIELD_MODIFICATION:
        return ("JVMTI_EVENT_FIELD_MODIFICATION");
    case JVMTI_EVENT_METHOD_ENTRY:
        return ("JVMTI_EVENT_METHOD_ENTRY");
    case JVMTI_EVENT_METHOD_EXIT:
        return ("JVMTI_EVENT_METHOD_EXIT");
    case JVMTI_EVENT_NATIVE_METHOD_BIND:
        return ("JVMTI_EVENT_NATIVE_METHOD_BIND");
    case JVMTI_EVENT_COMPILED_METHOD_LOAD:
        return ("JVMTI_EVENT_COMPILED_METHOD_LOAD");
    case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
        return ("JVMTI_EVENT_COMPILED_METHOD_UNLOAD");
    case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
        return ("JVMTI_EVENT_DYNAMIC_CODE_GENERATED");
    case JVMTI_EVENT_DATA_DUMP_REQUEST:
        return ("JVMTI_EVENT_DATA_DUMP_REQUEST");
    case JVMTI_EVENT_MONITOR_WAIT:
        return ("JVMTI_EVENT_MONITOR_WAIT");
    case JVMTI_EVENT_MONITOR_WAITED:
        return ("JVMTI_EVENT_MONITOR_WAITED");
    case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
        return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTER");
    case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
        return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTERED");
    case JVMTI_EVENT_GARBAGE_COLLECTION_START:
        return ("JVMTI_EVENT_GARBAGE_COLLECTION_START");
    case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
        return ("JVMTI_EVENT_GARBAGE_COLLECTION_FINISH");
    case JVMTI_EVENT_OBJECT_FREE:
        return ("JVMTI_EVENT_OBJECT_FREE");
    case JVMTI_EVENT_VM_OBJECT_ALLOC:
        return ("JVMTI_EVENT_VM_OBJECT_ALLOC");
    default:
        return ("");
    }
}

const char*
TranslateError(jvmtiError err) {
    switch (err) {
    case JVMTI_ERROR_NONE:
        return ("JVMTI_ERROR_NONE");
    case JVMTI_ERROR_INVALID_THREAD:
        return ("JVMTI_ERROR_INVALID_THREAD");
    case JVMTI_ERROR_INVALID_THREAD_GROUP:
        return ("JVMTI_ERROR_INVALID_THREAD_GROUP");
    case JVMTI_ERROR_INVALID_PRIORITY:
        return ("JVMTI_ERROR_INVALID_PRIORITY");
    case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
        return ("JVMTI_ERROR_THREAD_NOT_SUSPENDED");
    case JVMTI_ERROR_THREAD_SUSPENDED:
        return ("JVMTI_ERROR_THREAD_SUSPENDED");
    case JVMTI_ERROR_THREAD_NOT_ALIVE:
        return ("JVMTI_ERROR_THREAD_NOT_ALIVE");
    case JVMTI_ERROR_INVALID_OBJECT:
        return ("JVMTI_ERROR_INVALID_OBJECT");
    case JVMTI_ERROR_INVALID_CLASS:
        return ("JVMTI_ERROR_INVALID_CLASS");
    case JVMTI_ERROR_CLASS_NOT_PREPARED:
        return ("JVMTI_ERROR_CLASS_NOT_PREPARED");
    case JVMTI_ERROR_INVALID_METHODID:
        return ("JVMTI_ERROR_INVALID_METHODID");
    case JVMTI_ERROR_INVALID_LOCATION:
        return ("JVMTI_ERROR_INVALID_LOCATION");
    case JVMTI_ERROR_INVALID_FIELDID:
        return ("JVMTI_ERROR_INVALID_FIELDID");
    case JVMTI_ERROR_NO_MORE_FRAMES:
        return ("JVMTI_ERROR_NO_MORE_FRAMES");
    case JVMTI_ERROR_OPAQUE_FRAME:
        return ("JVMTI_ERROR_OPAQUE_FRAME");
    case JVMTI_ERROR_TYPE_MISMATCH:
        return ("JVMTI_ERROR_TYPE_MISMATCH");
    case JVMTI_ERROR_INVALID_SLOT:
        return ("JVMTI_ERROR_INVALID_SLOT");
    case JVMTI_ERROR_DUPLICATE:
        return ("JVMTI_ERROR_DUPLICATE");
    case JVMTI_ERROR_NOT_FOUND:
        return ("JVMTI_ERROR_NOT_FOUND");
    case JVMTI_ERROR_INVALID_MONITOR:
        return ("JVMTI_ERROR_INVALID_MONITOR");
    case JVMTI_ERROR_NOT_MONITOR_OWNER:
        return ("JVMTI_ERROR_NOT_MONITOR_OWNER");
    case JVMTI_ERROR_INTERRUPT:
        return ("JVMTI_ERROR_INTERRUPT");
    case JVMTI_ERROR_INVALID_CLASS_FORMAT:
        return ("JVMTI_ERROR_INVALID_CLASS_FORMAT");
    case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
        return ("JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
    case JVMTI_ERROR_FAILS_VERIFICATION:
        return ("JVMTI_ERROR_FAILS_VERIFICATION");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
    case JVMTI_ERROR_INVALID_TYPESTATE:
        return ("JVMTI_ERROR_INVALID_TYPESTATE");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
    case JVMTI_ERROR_UNSUPPORTED_VERSION:
        return ("JVMTI_ERROR_UNSUPPORTED_VERSION");
    case JVMTI_ERROR_NAMES_DONT_MATCH:
        return ("JVMTI_ERROR_NAMES_DONT_MATCH");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
    case JVMTI_ERROR_UNMODIFIABLE_CLASS:
        return ("JVMTI_ERROR_UNMODIFIABLE_CLASS");
    case JVMTI_ERROR_NOT_AVAILABLE:
        return ("JVMTI_ERROR_NOT_AVAILABLE");
    case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
        return ("JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
    case JVMTI_ERROR_NULL_POINTER:
        return ("JVMTI_ERROR_NULL_POINTER");
    case JVMTI_ERROR_ABSENT_INFORMATION:
        return ("JVMTI_ERROR_ABSENT_INFORMATION");
    case JVMTI_ERROR_INVALID_EVENT_TYPE:
        return ("JVMTI_ERROR_INVALID_EVENT_TYPE");
    case JVMTI_ERROR_ILLEGAL_ARGUMENT:
        return ("JVMTI_ERROR_ILLEGAL_ARGUMENT");
    case JVMTI_ERROR_NATIVE_METHOD:
        return ("JVMTI_ERROR_NATIVE_METHOD");
    case JVMTI_ERROR_OUT_OF_MEMORY:
        return ("JVMTI_ERROR_OUT_OF_MEMORY");
    case JVMTI_ERROR_ACCESS_DENIED:
        return ("JVMTI_ERROR_ACCESS_DENIED");
    case JVMTI_ERROR_WRONG_PHASE:
        return ("JVMTI_ERROR_WRONG_PHASE");
    case JVMTI_ERROR_INTERNAL:
        return ("JVMTI_ERROR_INTERNAL");
    case JVMTI_ERROR_UNATTACHED_THREAD:
        return ("JVMTI_ERROR_UNATTACHED_THREAD");
    case JVMTI_ERROR_INVALID_ENVIRONMENT:
        return ("JVMTI_ERROR_INVALID_ENVIRONMENT");
    default:
        return ("");
    }
}

const char*
TranslatePhase(jvmtiPhase phase) {
    switch (phase) {
    case JVMTI_PHASE_ONLOAD:
        return ("JVMTI_PHASE_ONLOAD");
    case JVMTI_PHASE_PRIMORDIAL:
        return ("JVMTI_PHASE_PRIMORDIAL");
    case JVMTI_PHASE_START:
        return ("JVMTI_PHASE_START");
    case JVMTI_PHASE_LIVE:
        return ("JVMTI_PHASE_LIVE");
    case JVMTI_PHASE_DEAD:
        return ("JVMTI_PHASE_DEAD");
    default:
        return ("");
    }
}

const char*
TranslateRootKind(jvmtiHeapRootKind root) {
    switch (root) {
    case JVMTI_HEAP_ROOT_JNI_GLOBAL:
        return ("JVMTI_HEAP_ROOT_JNI_GLOBAL");
    case JVMTI_HEAP_ROOT_JNI_LOCAL:
        return ("JVMTI_HEAP_ROOT_JNI_LOCAL");
    case JVMTI_HEAP_ROOT_SYSTEM_CLASS:
        return ("JVMTI_HEAP_ROOT_SYSTEM_CLASS");
    case JVMTI_HEAP_ROOT_MONITOR:
        return ("JVMTI_HEAP_ROOT_MONITOR");
    case JVMTI_HEAP_ROOT_STACK_LOCAL:
        return ("JVMTI_HEAP_ROOT_STACK_LOCAL");
    case JVMTI_HEAP_ROOT_THREAD:
        return ("JVMTI_HEAP_ROOT_THREAD");
    case JVMTI_HEAP_ROOT_OTHER:
        return ("JVMTI_HEAP_ROOT_OTHER");
    default:
        return ("");
    }
}

const char*
TranslateObjectRefKind(jvmtiObjectReferenceKind ref) {
    switch (ref) {
    case JVMTI_REFERENCE_CLASS:
        return ("JVMTI_REFERENCE_CLASS");
    case JVMTI_REFERENCE_FIELD:
        return ("JVMTI_REFERENCE_FIELD");
    case JVMTI_REFERENCE_ARRAY_ELEMENT:
        return ("JVMTI_REFERENCE_ARRAY_ELEMENT");
    case JVMTI_REFERENCE_CLASS_LOADER:
        return ("JVMTI_REFERENCE_CLASS_LOADER");
    case JVMTI_REFERENCE_SIGNERS:
        return ("JVMTI_REFERENCE_SIGNERS");
    case JVMTI_REFERENCE_PROTECTION_DOMAIN:
        return ("JVMTI_REFERENCE_PROTECTION_DOMAIN");
    case JVMTI_REFERENCE_INTERFACE:
        return ("JVMTI_REFERENCE_INTERFACE");
    case JVMTI_REFERENCE_STATIC_FIELD:
        return ("JVMTI_REFERENCE_STATIC_FIELD");
    case JVMTI_REFERENCE_CONSTANT_POOL:
        return ("JVMTI_REFERENCE_CONSTANT_POOL");
    default:
        return ("");
    }
}

int
isThreadExpected(jvmtiEnv *jvmti, jthread thread) {
  static const char *vm_jfr_buffer_thread_name = "VM JFR Buffer Thread";
  static const char *jfr_request_timer_thread_name = "JFR request timer";
  static const char *graal_management_bean_registration_thread_name =
                        "HotSpotGraalManagement Bean Registration";
  static const char *graal_compiler_thread_name_prefix = "JVMCI CompilerThread";
  static const size_t graal_prefix_length = strlen(graal_compiler_thread_name_prefix);

  static const char *unparker_thread_name_prefix = "VirtualThread-unparker";
  static const size_t unparker_prefix_length = strlen(unparker_thread_name_prefix);


  jvmtiThreadInfo threadinfo;
  jvmtiError err = jvmti->GetThreadInfo(thread, &threadinfo);
  if (err != JVMTI_ERROR_NONE) {
    return 0;
  }
  if (strcmp(threadinfo.name, vm_jfr_buffer_thread_name) == 0) {
    return 0;
  }
  if (strcmp(threadinfo.name, jfr_request_timer_thread_name) == 0) {
    return 0;
  }
  if (strcmp(threadinfo.name, graal_management_bean_registration_thread_name) == 0)
    return 0;

  if ((strlen(threadinfo.name) > graal_prefix_length) &&
      strncmp(threadinfo.name, graal_compiler_thread_name_prefix, graal_prefix_length) == 0) {
    return 0;
  }
  if (strncmp(threadinfo.name, unparker_thread_name_prefix, unparker_prefix_length) == 0) {
    return 0;
  }
  return 1;
}

jthread find_thread_by_name(jvmtiEnv* jvmti, JNIEnv* jni, const char name[]) {
  jthread* threads = NULL;
  jint count = 0;
  jthread found_thread = NULL;

  if (name == NULL) {
    return NULL;
  }

  check_jvmti_status(jni, jvmti->GetAllThreads(&count, &threads), "");

  for (int i = 0; i < count; i++) {
    jvmtiThreadInfo info = get_thread_info(jvmti, jni, threads[i]);
    if (info.name != NULL && strcmp(name, info.name) == 0) {
      found_thread = threads[i];
      break;
    }
  }

  check_jvmti_status(jni, jvmti->Deallocate((unsigned char*)threads), "");

  found_thread = (jthread) jni->NewGlobalRef(found_thread);
  return found_thread;
}

/*
 * JVMTI Extension Mechanism
 */

static const jvmtiEvent
  EXT_EVENT_VIRTUAL_THREAD_MOUNT   = (jvmtiEvent)((int)JVMTI_MIN_EVENT_TYPE_VAL - 2),
  EXT_EVENT_VIRTUAL_THREAD_UNMOUNT = (jvmtiEvent)((int)JVMTI_MIN_EVENT_TYPE_VAL - 3);

static jvmtiExtensionFunction
find_ext_function(jvmtiEnv* jvmti, JNIEnv* jni, const char* fname) {
  jint extCount = 0;
  jvmtiExtensionFunctionInfo* extList = NULL;

  jvmtiError err = jvmti->GetExtensionFunctions(&extCount, &extList);
  check_jvmti_status(jni, err, "jvmti_common find_ext_function: Error in JVMTI GetExtensionFunctions");

  for (int i = 0; i < extCount; i++) {
    if (strstr(extList[i].id, (char*)fname) != NULL) {
      return extList[i].func;
    }
  }
  return NULL;
}

static jvmtiError
GetVirtualThread(jvmtiEnv* jvmti, JNIEnv* jni, jthread cthread, jthread* vthread_ptr) {
  if (GetVirtualThread_func == NULL) { // lazily initialize function pointer
    GetVirtualThread_func = find_ext_function(jvmti, jni, "GetVirtualThread");
  }
  jvmtiError err = (*GetVirtualThread_func)(jvmti, cthread, vthread_ptr);

  return err;
}

static jvmtiError
GetCarrierThread(jvmtiEnv* jvmti, JNIEnv* jni, jthread vthread, jthread* cthread_ptr) {
  if (GetCarrierThread_func == NULL) { // lazily initialize function pointer
    GetCarrierThread_func = find_ext_function(jvmti, jni, "GetCarrierThread");
  }
  jvmtiError err = (*GetCarrierThread_func)(jvmti, vthread, cthread_ptr);

  return err;
}

static jthread
get_virtual_thread(jvmtiEnv* jvmti, JNIEnv* jni, jthread cthread) {
  jthread vthread = NULL;
  jvmtiError err = GetVirtualThread(jvmti, jni, cthread, &vthread);
  check_jvmti_status(jni, err, "jvmti_common get_virtual_thread: Error in JVMTI extension GetVirtualThread");
  return vthread;
}

static jthread
get_carrier_thread(jvmtiEnv* jvmti, JNIEnv* jni, jthread vthread) {
  jthread cthread = NULL;
  jvmtiError err = GetCarrierThread(jvmti, jni, vthread, &cthread);
  check_jvmti_status(jni, err, "jvmti_common get_carrier_thread: Error in JVMTI extension GetCarrierThread");

  return cthread;
}

static jvmtiExtensionEventInfo*
find_ext_event(jvmtiEnv* jvmti, const char* ename) {
  jint extCount = 0;
  jvmtiExtensionEventInfo* extList = NULL;

  jvmtiError err = jvmti->GetExtensionEvents(&extCount, &extList);
  if (err != JVMTI_ERROR_NONE) {
    LOG("jvmti_common find_ext_event: Error in JVMTI GetExtensionFunctions: %s(%d)\n",TranslateError(err), err);
    return NULL;
  }
  for (int i = 0; i < extCount; i++) {
    if (strstr(extList[i].id, (char*)ename) != NULL) {
      return &extList[i];
    }
  }
  return NULL;
}

static jvmtiError
set_ext_event_callback(jvmtiEnv* jvmti,  const char* ename, jvmtiExtensionEvent callback) {
  jvmtiExtensionEventInfo* info = find_ext_event(jvmti, ename);

  if (info == NULL) {
    LOG("jvmti_common set_ext_event_callback: Extension event was not found: %s\n", ename);
    return JVMTI_ERROR_NOT_AVAILABLE;
  }
  jvmtiError err = jvmti->SetExtensionEventCallback(info->extension_event_index, callback);
  return err;
}

/** Enable or disable given events. */

static jvmtiError
set_event_notification_mode(jvmtiEnv* jvmti, jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread) {
  jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread);
  return err;
}

static void
set_event_notification_mode(jvmtiEnv* jvmti, JNIEnv* jni, jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread) {
  jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread);
  check_jvmti_status(jni, err, "jvmti_common set_event_notification_mode: Error in JVMTI SetEventNotificationMode");
}

int
enable_events_notifications(jvmtiEnv* jvmti, JNIEnv* jni, jvmtiEventMode enable, int size, jvmtiEvent list[], jthread thread) {
  for (int i = 0; i < size; i++) {
    check_jvmti_status(jni, jvmti->SetEventNotificationMode(enable, list[i], thread), "");
  }
  return JNI_TRUE;
}

void
sleep_ms(int millis) {
#ifdef _WIN32
  Sleep(millis);
#else
  usleep(1000 * millis);
#endif
}

void
sleep_sec(jlong timeout) {
  int seconds = (int)((timeout + 999) / 1000);
#ifdef _WIN32
  Sleep(1000L * seconds);
#else
  sleep(seconds);
#endif
}

#endif

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




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 ist noch experimentell.


Bot Zugriff