diff options
Diffstat (limited to 'runtime/openjdkjvmti/OpenjdkJvmTi.cc')
| -rw-r--r-- | runtime/openjdkjvmti/OpenjdkJvmTi.cc | 447 |
1 files changed, 311 insertions, 136 deletions
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index 450b6b6bcf..39e603e1e7 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -35,7 +35,7 @@ #include <jni.h> -#include "openjdkjvmti/jvmti.h" +#include "jvmti.h" #include "art_jvmti.h" #include "base/logging.h" @@ -66,10 +66,6 @@ #include "ti_timers.h" #include "transform.h" -// TODO Remove this at some point by annotating all the methods. It was put in to make the skeleton -// easier to create. -#pragma GCC diagnostic ignored "-Wunused-parameter" - namespace openjdkjvmti { EventHandler gEventHandler; @@ -83,20 +79,26 @@ EventHandler gEventHandler; class JvmtiFunctions { private: - static bool IsValidEnv(jvmtiEnv* env) { - return env != nullptr; + static jvmtiError getEnvironmentError(jvmtiEnv* env) { + if (env == nullptr) { + return ERR(INVALID_ENVIRONMENT); + } else if (art::Thread::Current() == nullptr) { + return ERR(UNATTACHED_THREAD); + } else { + return OK; + } } -#define ENSURE_VALID_ENV(env) \ - do { \ - if (!IsValidEnv(env)) { \ - return ERR(INVALID_ENVIRONMENT); \ - } \ +#define ENSURE_VALID_ENV(env) \ + do { \ + jvmtiError ensure_valid_env_ ## __LINE__ = getEnvironmentError(env); \ + if (ensure_valid_env_ ## __LINE__ != OK) { \ + return ensure_valid_env_ ## __LINE__ ; \ + } \ } while (false) #define ENSURE_HAS_CAP(env, cap) \ do { \ - ENSURE_VALID_ENV(env); \ if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.cap != 1) { \ return ERR(MUST_POSSESS_CAPABILITY); \ } \ @@ -125,76 +127,92 @@ class JvmtiFunctions { } static jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr) { + ENSURE_VALID_ENV(env); return ThreadUtil::GetThreadState(env, thread, thread_state_ptr); } static jvmtiError GetCurrentThread(jvmtiEnv* env, jthread* thread_ptr) { + ENSURE_VALID_ENV(env); return ThreadUtil::GetCurrentThread(env, thread_ptr); } static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr) { + ENSURE_VALID_ENV(env); return ThreadUtil::GetAllThreads(env, threads_count_ptr, threads_ptr); } - static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread) { + static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_suspend); return ERR(NOT_IMPLEMENTED); } static jvmtiError SuspendThreadList(jvmtiEnv* env, - jint request_count, - const jthread* request_list, - jvmtiError* results) { + jint request_count ATTRIBUTE_UNUSED, + const jthread* request_list ATTRIBUTE_UNUSED, + jvmtiError* results ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_suspend); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread) { + static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_suspend); return ERR(NOT_IMPLEMENTED); } static jvmtiError ResumeThreadList(jvmtiEnv* env, - jint request_count, - const jthread* request_list, - jvmtiError* results) { + jint request_count ATTRIBUTE_UNUSED, + const jthread* request_list ATTRIBUTE_UNUSED, + jvmtiError* results ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_suspend); return ERR(NOT_IMPLEMENTED); } - static jvmtiError StopThread(jvmtiEnv* env, jthread thread, jobject exception) { + static jvmtiError StopThread(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jobject exception ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_signal_thread); return ERR(NOT_IMPLEMENTED); } - static jvmtiError InterruptThread(jvmtiEnv* env, jthread thread) { + static jvmtiError InterruptThread(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_signal_thread); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) { + ENSURE_VALID_ENV(env); return ThreadUtil::GetThreadInfo(env, thread, info_ptr); } static jvmtiError GetOwnedMonitorInfo(jvmtiEnv* env, - jthread thread, - jint* owned_monitor_count_ptr, - jobject** owned_monitors_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint* owned_monitor_count_ptr ATTRIBUTE_UNUSED, + jobject** owned_monitors_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_owned_monitor_info); return ERR(NOT_IMPLEMENTED); } - static jvmtiError GetOwnedMonitorStackDepthInfo(jvmtiEnv* env, - jthread thread, - jint* monitor_info_count_ptr, - jvmtiMonitorStackDepthInfo** monitor_info_ptr) { + static jvmtiError GetOwnedMonitorStackDepthInfo( + jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jint* monitor_info_count_ptr ATTRIBUTE_UNUSED, + jvmtiMonitorStackDepthInfo** monitor_info_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_owned_monitor_stack_depth_info); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetCurrentContendedMonitor(jvmtiEnv* env, - jthread thread, - jobject* monitor_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jobject* monitor_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_current_contended_monitor); return ERR(NOT_IMPLEMENTED); } @@ -204,26 +222,31 @@ class JvmtiFunctions { jvmtiStartFunction proc, const void* arg, jint priority) { + ENSURE_VALID_ENV(env); return ThreadUtil::RunAgentThread(env, thread, proc, arg, priority); } static jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) { + ENSURE_VALID_ENV(env); return ThreadUtil::SetThreadLocalStorage(env, thread, data); } static jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr) { + ENSURE_VALID_ENV(env); return ThreadUtil::GetThreadLocalStorage(env, thread, data_ptr); } static jvmtiError GetTopThreadGroups(jvmtiEnv* env, jint* group_count_ptr, jthreadGroup** groups_ptr) { + ENSURE_VALID_ENV(env); return ThreadGroupUtil::GetTopThreadGroups(env, group_count_ptr, groups_ptr); } static jvmtiError GetThreadGroupInfo(jvmtiEnv* env, jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) { + ENSURE_VALID_ENV(env); return ThreadGroupUtil::GetThreadGroupInfo(env, group, info_ptr); } @@ -233,6 +256,7 @@ class JvmtiFunctions { jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) { + ENSURE_VALID_ENV(env); return ThreadGroupUtil::GetThreadGroupChildren(env, group, thread_count_ptr, @@ -247,6 +271,7 @@ class JvmtiFunctions { jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) { + ENSURE_VALID_ENV(env); return StackUtil::GetStackTrace(env, thread, start_depth, @@ -259,6 +284,7 @@ class JvmtiFunctions { jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) { + ENSURE_VALID_ENV(env); return StackUtil::GetAllStackTraces(env, max_frame_count, stack_info_ptr, thread_count_ptr); } @@ -267,6 +293,7 @@ class JvmtiFunctions { const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) { + ENSURE_VALID_ENV(env); return StackUtil::GetThreadListStackTraces(env, thread_count, thread_list, @@ -275,10 +302,12 @@ class JvmtiFunctions { } static jvmtiError GetFrameCount(jvmtiEnv* env, jthread thread, jint* count_ptr) { + ENSURE_VALID_ENV(env); return StackUtil::GetFrameCount(env, thread, count_ptr); } - static jvmtiError PopFrame(jvmtiEnv* env, jthread thread) { + static jvmtiError PopFrame(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_pop_frame); return ERR(NOT_IMPLEMENTED); } @@ -288,40 +317,60 @@ class JvmtiFunctions { jint depth, jmethodID* method_ptr, jlocation* location_ptr) { + ENSURE_VALID_ENV(env); return StackUtil::GetFrameLocation(env, thread, depth, method_ptr, location_ptr); } - static jvmtiError NotifyFramePop(jvmtiEnv* env, jthread thread, jint depth) { + static jvmtiError NotifyFramePop(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_frame_pop_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnObject(jvmtiEnv* env, jthread thread, jobject value) { + static jvmtiError ForceEarlyReturnObject(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jobject value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnInt(jvmtiEnv* env, jthread thread, jint value) { + static jvmtiError ForceEarlyReturnInt(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jint value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnLong(jvmtiEnv* env, jthread thread, jlong value) { + static jvmtiError ForceEarlyReturnLong(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jlong value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnFloat(jvmtiEnv* env, jthread thread, jfloat value) { + static jvmtiError ForceEarlyReturnFloat(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jfloat value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnDouble(jvmtiEnv* env, jthread thread, jdouble value) { + static jvmtiError ForceEarlyReturnDouble(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jdouble value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ForceEarlyReturnVoid(jvmtiEnv* env, jthread thread) { + static jvmtiError ForceEarlyReturnVoid(jvmtiEnv* env, jthread thread ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_force_early_return); return ERR(NOT_IMPLEMENTED); } @@ -332,6 +381,7 @@ class JvmtiFunctions { jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get()); return heap_util.FollowReferences(env, @@ -347,12 +397,14 @@ class JvmtiFunctions { jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get()); return heap_util.IterateThroughHeap(env, heap_filter, klass, callbacks, user_data); } static jvmtiError GetTag(jvmtiEnv* env, jobject object, jlong* tag_ptr) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); JNIEnv* jni_env = GetJniEnv(env); @@ -370,6 +422,7 @@ class JvmtiFunctions { } static jvmtiError SetTag(jvmtiEnv* env, jobject object, jlong tag) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); if (object == nullptr) { @@ -394,6 +447,7 @@ class JvmtiFunctions { jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); JNIEnv* jni_env = GetJniEnv(env); @@ -411,173 +465,210 @@ class JvmtiFunctions { } static jvmtiError ForceGarbageCollection(jvmtiEnv* env) { + ENSURE_VALID_ENV(env); return HeapUtil::ForceGarbageCollection(env); } static jvmtiError IterateOverObjectsReachableFromObject( jvmtiEnv* env, - jobject object, - jvmtiObjectReferenceCallback object_reference_callback, - const void* user_data) { + jobject object ATTRIBUTE_UNUSED, + jvmtiObjectReferenceCallback object_reference_callback ATTRIBUTE_UNUSED, + const void* user_data ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); return ERR(NOT_IMPLEMENTED); } - static jvmtiError IterateOverReachableObjects(jvmtiEnv* env, - jvmtiHeapRootCallback heap_root_callback, - jvmtiStackReferenceCallback stack_ref_callback, - jvmtiObjectReferenceCallback object_ref_callback, - const void* user_data) { + static jvmtiError IterateOverReachableObjects( + jvmtiEnv* env, + jvmtiHeapRootCallback heap_root_callback ATTRIBUTE_UNUSED, + jvmtiStackReferenceCallback stack_ref_callback ATTRIBUTE_UNUSED, + jvmtiObjectReferenceCallback object_ref_callback ATTRIBUTE_UNUSED, + const void* user_data ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); return ERR(NOT_IMPLEMENTED); } static jvmtiError IterateOverHeap(jvmtiEnv* env, - jvmtiHeapObjectFilter object_filter, - jvmtiHeapObjectCallback heap_object_callback, - const void* user_data) { + jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED, + jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED, + const void* user_data ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); return ERR(NOT_IMPLEMENTED); } - static jvmtiError IterateOverInstancesOfClass(jvmtiEnv* env, - jclass klass, - jvmtiHeapObjectFilter object_filter, - jvmtiHeapObjectCallback heap_object_callback, - const void* user_data) { + static jvmtiError IterateOverInstancesOfClass( + jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jvmtiHeapObjectFilter object_filter ATTRIBUTE_UNUSED, + jvmtiHeapObjectCallback heap_object_callback ATTRIBUTE_UNUSED, + const void* user_data ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_tag_objects); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalObject(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jobject* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jobject* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalInstance(jvmtiEnv* env, - jthread thread, - jint depth, - jobject* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jobject* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalInt(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jint* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jint* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalLong(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jlong* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jlong* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalFloat(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jfloat* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jfloat* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLocalDouble(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jdouble* value_ptr) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jdouble* value_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError SetLocalObject(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jobject value) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jobject value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError SetLocalInt(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jint value) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jint value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError SetLocalLong(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jlong value) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jlong value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError SetLocalFloat(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jfloat value) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jfloat value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError SetLocalDouble(jvmtiEnv* env, - jthread thread, - jint depth, - jint slot, - jdouble value) { + jthread thread ATTRIBUTE_UNUSED, + jint depth ATTRIBUTE_UNUSED, + jint slot ATTRIBUTE_UNUSED, + jdouble value ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } - static jvmtiError SetBreakpoint(jvmtiEnv* env, jmethodID method, jlocation location) { + static jvmtiError SetBreakpoint(jvmtiEnv* env, + jmethodID method ATTRIBUTE_UNUSED, + jlocation location ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_breakpoint_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ClearBreakpoint(jvmtiEnv* env, jmethodID method, jlocation location) { + static jvmtiError ClearBreakpoint(jvmtiEnv* env, + jmethodID method ATTRIBUTE_UNUSED, + jlocation location ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_breakpoint_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError SetFieldAccessWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + static jvmtiError SetFieldAccessWatch(jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jfieldID field ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_field_access_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ClearFieldAccessWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + static jvmtiError ClearFieldAccessWatch(jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jfieldID field ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_field_access_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError SetFieldModificationWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + static jvmtiError SetFieldModificationWatch(jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jfieldID field ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_field_modification_events); return ERR(NOT_IMPLEMENTED); } - static jvmtiError ClearFieldModificationWatch(jvmtiEnv* env, jclass klass, jfieldID field) { + static jvmtiError ClearFieldModificationWatch(jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jfieldID field ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_generate_field_modification_events); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetLoadedClasses(jvmtiEnv* env, jint* class_count_ptr, jclass** classes_ptr) { + ENSURE_VALID_ENV(env); HeapUtil heap_util(ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get()); return heap_util.GetLoadedClasses(env, class_count_ptr, classes_ptr); } @@ -586,6 +677,7 @@ class JvmtiFunctions { jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassLoaderClasses(env, initiating_loader, class_count_ptr, classes_ptr); } @@ -593,19 +685,25 @@ class JvmtiFunctions { jclass klass, char** signature_ptr, char** generic_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassSignature(env, klass, signature_ptr, generic_ptr); } static jvmtiError GetClassStatus(jvmtiEnv* env, jclass klass, jint* status_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassStatus(env, klass, status_ptr); } - static jvmtiError GetSourceFileName(jvmtiEnv* env, jclass klass, char** source_name_ptr) { + static jvmtiError GetSourceFileName(jvmtiEnv* env, + jclass klass ATTRIBUTE_UNUSED, + char** source_name_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_source_file_name); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassModifiers(env, klass, modifiers_ptr); } @@ -613,6 +711,7 @@ class JvmtiFunctions { jclass klass, jint* method_count_ptr, jmethodID** methods_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassMethods(env, klass, method_count_ptr, methods_ptr); } @@ -620,6 +719,7 @@ class JvmtiFunctions { jclass klass, jint* field_count_ptr, jfieldID** fields_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassFields(env, klass, field_count_ptr, fields_ptr); } @@ -627,6 +727,7 @@ class JvmtiFunctions { jclass klass, jint* interface_count_ptr, jclass** interfaces_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetImplementedInterfaces(env, klass, interface_count_ptr, interfaces_ptr); } @@ -634,46 +735,54 @@ class JvmtiFunctions { jclass klass, jint* minor_version_ptr, jint* major_version_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassVersionNumbers(env, klass, minor_version_ptr, major_version_ptr); } static jvmtiError GetConstantPool(jvmtiEnv* env, - jclass klass, - jint* constant_pool_count_ptr, - jint* constant_pool_byte_count_ptr, - unsigned char** constant_pool_bytes_ptr) { + jclass klass ATTRIBUTE_UNUSED, + jint* constant_pool_count_ptr ATTRIBUTE_UNUSED, + jint* constant_pool_byte_count_ptr ATTRIBUTE_UNUSED, + unsigned char** constant_pool_bytes_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_constant_pool); return ERR(NOT_IMPLEMENTED); } static jvmtiError IsInterface(jvmtiEnv* env, jclass klass, jboolean* is_interface_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::IsInterface(env, klass, is_interface_ptr); } static jvmtiError IsArrayClass(jvmtiEnv* env, jclass klass, jboolean* is_array_class_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::IsArrayClass(env, klass, is_array_class_ptr); } static jvmtiError IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_modifiable_class_ptr) { + ENSURE_VALID_ENV(env); return Redefiner::IsModifiableClass(env, klass, is_modifiable_class_ptr); } static jvmtiError GetClassLoader(jvmtiEnv* env, jclass klass, jobject* classloader_ptr) { + ENSURE_VALID_ENV(env); return ClassUtil::GetClassLoader(env, klass, classloader_ptr); } static jvmtiError GetSourceDebugExtension(jvmtiEnv* env, - jclass klass, - char** source_debug_extension_ptr) { + jclass klass ATTRIBUTE_UNUSED, + char** source_debug_extension_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_source_debug_extension); return ERR(NOT_IMPLEMENTED); } static jvmtiError RetransformClasses(jvmtiEnv* env, jint class_count, const jclass* classes) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_retransform_classes); std::string error_msg; jvmtiError res = Transformer::RetransformClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env), @@ -692,6 +801,7 @@ class JvmtiFunctions { static jvmtiError RedefineClasses(jvmtiEnv* env, jint class_count, const jvmtiClassDefinition* class_definitions) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_redefine_classes); std::string error_msg; jvmtiError res = Redefiner::RedefineClasses(ArtJvmTiEnv::AsArtJvmTiEnv(env), @@ -708,16 +818,19 @@ class JvmtiFunctions { } static jvmtiError GetObjectSize(jvmtiEnv* env, jobject object, jlong* size_ptr) { + ENSURE_VALID_ENV(env); return ObjectUtil::GetObjectSize(env, object, size_ptr); } static jvmtiError GetObjectHashCode(jvmtiEnv* env, jobject object, jint* hash_code_ptr) { + ENSURE_VALID_ENV(env); return ObjectUtil::GetObjectHashCode(env, object, hash_code_ptr); } static jvmtiError GetObjectMonitorUsage(jvmtiEnv* env, - jobject object, - jvmtiMonitorUsage* info_ptr) { + jobject object ATTRIBUTE_UNUSED, + jvmtiMonitorUsage* info_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_monitor_info); return ERR(NOT_IMPLEMENTED); } @@ -728,6 +841,7 @@ class JvmtiFunctions { char** name_ptr, char** signature_ptr, char** generic_ptr) { + ENSURE_VALID_ENV(env); return FieldUtil::GetFieldName(env, klass, field, name_ptr, signature_ptr, generic_ptr); } @@ -735,6 +849,7 @@ class JvmtiFunctions { jclass klass, jfieldID field, jclass* declaring_class_ptr) { + ENSURE_VALID_ENV(env); return FieldUtil::GetFieldDeclaringClass(env, klass, field, declaring_class_ptr); } @@ -742,6 +857,7 @@ class JvmtiFunctions { jclass klass, jfieldID field, jint* modifiers_ptr) { + ENSURE_VALID_ENV(env); return FieldUtil::GetFieldModifiers(env, klass, field, modifiers_ptr); } @@ -749,6 +865,7 @@ class JvmtiFunctions { jclass klass, jfieldID field, jboolean* is_synthetic_ptr) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_synthetic_attribute); return FieldUtil::IsFieldSynthetic(env, klass, field, is_synthetic_ptr); } @@ -758,30 +875,35 @@ class JvmtiFunctions { char** name_ptr, char** signature_ptr, char** generic_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetMethodName(env, method, name_ptr, signature_ptr, generic_ptr); } static jvmtiError GetMethodDeclaringClass(jvmtiEnv* env, jmethodID method, jclass* declaring_class_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetMethodDeclaringClass(env, method, declaring_class_ptr); } static jvmtiError GetMethodModifiers(jvmtiEnv* env, jmethodID method, jint* modifiers_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetMethodModifiers(env, method, modifiers_ptr); } static jvmtiError GetMaxLocals(jvmtiEnv* env, jmethodID method, jint* max_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetMaxLocals(env, method, max_ptr); } static jvmtiError GetArgumentsSize(jvmtiEnv* env, jmethodID method, jint* size_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetArgumentsSize(env, method, size_ptr); } @@ -789,6 +911,7 @@ class JvmtiFunctions { jmethodID method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_line_numbers); return MethodUtil::GetLineNumberTable(env, method, entry_count_ptr, table_ptr); } @@ -797,81 +920,100 @@ class JvmtiFunctions { jmethodID method, jlocation* start_location_ptr, jlocation* end_location_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::GetMethodLocation(env, method, start_location_ptr, end_location_ptr); } static jvmtiError GetLocalVariableTable(jvmtiEnv* env, - jmethodID method, - jint* entry_count_ptr, - jvmtiLocalVariableEntry** table_ptr) { + jmethodID method ATTRIBUTE_UNUSED, + jint* entry_count_ptr ATTRIBUTE_UNUSED, + jvmtiLocalVariableEntry** table_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_access_local_variables); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetBytecodes(jvmtiEnv* env, - jmethodID method, - jint* bytecode_count_ptr, - unsigned char** bytecodes_ptr) { + jmethodID method ATTRIBUTE_UNUSED, + jint* bytecode_count_ptr ATTRIBUTE_UNUSED, + unsigned char** bytecodes_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_bytecodes); return ERR(NOT_IMPLEMENTED); } static jvmtiError IsMethodNative(jvmtiEnv* env, jmethodID method, jboolean* is_native_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::IsMethodNative(env, method, is_native_ptr); } static jvmtiError IsMethodSynthetic(jvmtiEnv* env, jmethodID method, jboolean* is_synthetic_ptr) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_synthetic_attribute); return MethodUtil::IsMethodSynthetic(env, method, is_synthetic_ptr); } static jvmtiError IsMethodObsolete(jvmtiEnv* env, jmethodID method, jboolean* is_obsolete_ptr) { + ENSURE_VALID_ENV(env); return MethodUtil::IsMethodObsolete(env, method, is_obsolete_ptr); } - static jvmtiError SetNativeMethodPrefix(jvmtiEnv* env, const char* prefix) { + static jvmtiError SetNativeMethodPrefix(jvmtiEnv* env, const char* prefix ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_set_native_method_prefix); return ERR(NOT_IMPLEMENTED); } - static jvmtiError SetNativeMethodPrefixes(jvmtiEnv* env, jint prefix_count, char** prefixes) { + static jvmtiError SetNativeMethodPrefixes(jvmtiEnv* env, + jint prefix_count ATTRIBUTE_UNUSED, + char** prefixes ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_set_native_method_prefix); return ERR(NOT_IMPLEMENTED); } static jvmtiError CreateRawMonitor(jvmtiEnv* env, const char* name, jrawMonitorID* monitor_ptr) { + ENSURE_VALID_ENV(env); return MonitorUtil::CreateRawMonitor(env, name, monitor_ptr); } static jvmtiError DestroyRawMonitor(jvmtiEnv* env, jrawMonitorID monitor) { + ENSURE_VALID_ENV(env); return MonitorUtil::DestroyRawMonitor(env, monitor); } static jvmtiError RawMonitorEnter(jvmtiEnv* env, jrawMonitorID monitor) { + ENSURE_VALID_ENV(env); return MonitorUtil::RawMonitorEnter(env, monitor); } static jvmtiError RawMonitorExit(jvmtiEnv* env, jrawMonitorID monitor) { + ENSURE_VALID_ENV(env); return MonitorUtil::RawMonitorExit(env, monitor); } static jvmtiError RawMonitorWait(jvmtiEnv* env, jrawMonitorID monitor, jlong millis) { + ENSURE_VALID_ENV(env); return MonitorUtil::RawMonitorWait(env, monitor, millis); } static jvmtiError RawMonitorNotify(jvmtiEnv* env, jrawMonitorID monitor) { + ENSURE_VALID_ENV(env); return MonitorUtil::RawMonitorNotify(env, monitor); } static jvmtiError RawMonitorNotifyAll(jvmtiEnv* env, jrawMonitorID monitor) { + ENSURE_VALID_ENV(env); return MonitorUtil::RawMonitorNotifyAll(env, monitor); } static jvmtiError SetJNIFunctionTable(jvmtiEnv* env, const jniNativeInterface* function_table) { + ENSURE_VALID_ENV(env); return JNIUtil::SetJNIFunctionTable(env, function_table); } static jvmtiError GetJNIFunctionTable(jvmtiEnv* env, jniNativeInterface** function_table) { + ENSURE_VALID_ENV(env); return JNIUtil::GetJNIFunctionTable(env, function_table); } @@ -926,13 +1068,16 @@ class JvmtiFunctions { return gEventHandler.SetEvent(art_env, art_thread, GetArtJvmtiEvent(art_env, event_type), mode); } - static jvmtiError GenerateEvents(jvmtiEnv* env, jvmtiEvent event_type) { - return ERR(NOT_IMPLEMENTED); + static jvmtiError GenerateEvents(jvmtiEnv* env, + jvmtiEvent event_type ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); + return OK; } static jvmtiError GetExtensionFunctions(jvmtiEnv* env, jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) { + ENSURE_VALID_ENV(env); // We do not have any extension functions. *extension_count_ptr = 0; *extensions = nullptr; @@ -943,6 +1088,7 @@ class JvmtiFunctions { static jvmtiError GetExtensionEvents(jvmtiEnv* env, jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) { + ENSURE_VALID_ENV(env); // We do not have any extension events. *extension_count_ptr = 0; *extensions = nullptr; @@ -951,8 +1097,9 @@ class JvmtiFunctions { } static jvmtiError SetExtensionEventCallback(jvmtiEnv* env, - jint extension_event_index, - jvmtiExtensionEvent callback) { + jint extension_event_index ATTRIBUTE_UNUSED, + jvmtiExtensionEvent callback ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); // We do not have any extension events, so any call is illegal. return ERR(ILLEGAL_ARGUMENT); } @@ -969,11 +1116,16 @@ class JvmtiFunctions { ENSURE_NON_NULL(capabilities_ptr); ArtJvmTiEnv* art_env = static_cast<ArtJvmTiEnv*>(env); jvmtiError ret = OK; - jvmtiCapabilities changed; + jvmtiCapabilities changed = {}; + jvmtiCapabilities potential_capabilities = {}; + ret = env->GetPotentialCapabilities(&potential_capabilities); + if (ret != OK) { + return ret; + } #define ADD_CAPABILITY(e) \ do { \ if (capabilities_ptr->e == 1) { \ - if (kPotentialCapabilities.e == 1) { \ + if (potential_capabilities.e == 1) { \ if (art_env->capabilities.e != 1) { \ art_env->capabilities.e = 1; \ changed.e = 1; \ @@ -1037,7 +1189,7 @@ class JvmtiFunctions { ENSURE_VALID_ENV(env); ENSURE_NON_NULL(capabilities_ptr); ArtJvmTiEnv* art_env = reinterpret_cast<ArtJvmTiEnv*>(env); - jvmtiCapabilities changed; + jvmtiCapabilities changed = {}; #define DEL_CAPABILITY(e) \ do { \ if (capabilities_ptr->e == 1) { \ @@ -1104,59 +1256,76 @@ class JvmtiFunctions { return OK; } - static jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + static jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiEnv* env, + jvmtiTimerInfo* info_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_current_thread_cpu_time); return ERR(NOT_IMPLEMENTED); } - static jvmtiError GetCurrentThreadCpuTime(jvmtiEnv* env, jlong* nanos_ptr) { + static jvmtiError GetCurrentThreadCpuTime(jvmtiEnv* env, jlong* nanos_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_current_thread_cpu_time); return ERR(NOT_IMPLEMENTED); } - static jvmtiError GetThreadCpuTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + static jvmtiError GetThreadCpuTimerInfo(jvmtiEnv* env, + jvmtiTimerInfo* info_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_thread_cpu_time); return ERR(NOT_IMPLEMENTED); } - static jvmtiError GetThreadCpuTime(jvmtiEnv* env, jthread thread, jlong* nanos_ptr) { + static jvmtiError GetThreadCpuTime(jvmtiEnv* env, + jthread thread ATTRIBUTE_UNUSED, + jlong* nanos_ptr ATTRIBUTE_UNUSED) { + ENSURE_VALID_ENV(env); ENSURE_HAS_CAP(env, can_get_thread_cpu_time); return ERR(NOT_IMPLEMENTED); } static jvmtiError GetTimerInfo(jvmtiEnv* env, jvmtiTimerInfo* info_ptr) { + ENSURE_VALID_ENV(env); return TimerUtil::GetTimerInfo(env, info_ptr); } static jvmtiError GetTime(jvmtiEnv* env, jlong* nanos_ptr) { + ENSURE_VALID_ENV(env); return TimerUtil::GetTime(env, nanos_ptr); } static jvmtiError GetAvailableProcessors(jvmtiEnv* env, jint* processor_count_ptr) { + ENSURE_VALID_ENV(env); return TimerUtil::GetAvailableProcessors(env, processor_count_ptr); } static jvmtiError AddToBootstrapClassLoaderSearch(jvmtiEnv* env, const char* segment) { + ENSURE_VALID_ENV(env); return SearchUtil::AddToBootstrapClassLoaderSearch(env, segment); } static jvmtiError AddToSystemClassLoaderSearch(jvmtiEnv* env, const char* segment) { + ENSURE_VALID_ENV(env); return SearchUtil::AddToSystemClassLoaderSearch(env, segment); } static jvmtiError GetSystemProperties(jvmtiEnv* env, jint* count_ptr, char*** property_ptr) { + ENSURE_VALID_ENV(env); return PropertiesUtil::GetSystemProperties(env, count_ptr, property_ptr); } static jvmtiError GetSystemProperty(jvmtiEnv* env, const char* property, char** value_ptr) { + ENSURE_VALID_ENV(env); return PropertiesUtil::GetSystemProperty(env, property, value_ptr); } static jvmtiError SetSystemProperty(jvmtiEnv* env, const char* property, const char* value) { + ENSURE_VALID_ENV(env); return PropertiesUtil::SetSystemProperty(env, property, value); } static jvmtiError GetPhase(jvmtiEnv* env, jvmtiPhase* phase_ptr) { + ENSURE_VALID_ENV(env); return PhaseUtil::GetPhase(env, phase_ptr); } @@ -1264,7 +1433,10 @@ class JvmtiFunctions { } } - static jvmtiError SetVerboseFlag(jvmtiEnv* env, jvmtiVerboseFlag flag, jboolean value) { + static jvmtiError SetVerboseFlag(jvmtiEnv* env, + jvmtiVerboseFlag flag, + jboolean value) { + ENSURE_VALID_ENV(env); if (flag == jvmtiVerboseFlag::JVMTI_VERBOSE_OTHER) { // OTHER is special, as it's 0, so can't do a bit check. bool val = (value == JNI_TRUE) ? true : false; @@ -1319,6 +1491,7 @@ class JvmtiFunctions { } static jvmtiError GetJLocationFormat(jvmtiEnv* env, jvmtiJlocationFormat* format_ptr) { + ENSURE_VALID_ENV(env); // Report BCI as jlocation format. We report dex bytecode indices. if (format_ptr == nullptr) { return ERR(NULL_POINTER); @@ -1340,8 +1513,8 @@ extern const jvmtiInterface_1 gJvmtiInterface; ArtJvmTiEnv::ArtJvmTiEnv(art::JavaVMExt* runtime, EventHandler* event_handler) : art_vm(runtime), local_data(nullptr), - capabilities(), - object_tag_table(new ObjectTagTable(event_handler)) { + capabilities() { + object_tag_table = std::unique_ptr<ObjectTagTable>(new ObjectTagTable(event_handler, this)); functions = &gJvmtiInterface; } @@ -1384,6 +1557,7 @@ extern "C" bool ArtPlugin_Initialize() { ClassUtil::Register(&gEventHandler); DumpUtil::Register(&gEventHandler); SearchUtil::Register(); + HeapUtil::Register(); runtime->GetJavaVM()->AddEnvironmentHook(GetEnvHandler); @@ -1396,6 +1570,7 @@ extern "C" bool ArtPlugin_Deinitialize() { ClassUtil::Unregister(); DumpUtil::Unregister(); SearchUtil::Unregister(); + HeapUtil::Unregister(); return true; } |