Home | History | Annotate | Download | only in ti-agent
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "jvmti_helper.h"
     18 #include "test_env.h"
     19 
     20 #include <dlfcn.h>
     21 
     22 #include <algorithm>
     23 #include <cstdio>
     24 #include <cstring>
     25 #include <sstream>
     26 
     27 #include "android-base/logging.h"
     28 #include "scoped_local_ref.h"
     29 
     30 namespace art {
     31 
     32 void CheckJvmtiError(jvmtiEnv* env, jvmtiError error) {
     33   if (error != JVMTI_ERROR_NONE) {
     34     char* error_name;
     35     jvmtiError name_error = env->GetErrorName(error, &error_name);
     36     if (name_error != JVMTI_ERROR_NONE) {
     37       LOG(FATAL) << "Unable to get error name for " << error;
     38     }
     39     LOG(FATAL) << "Unexpected error: " << error_name;
     40   }
     41 }
     42 
     43 // These are a set of capabilities we will enable in all situations. These are chosen since they
     44 // will not affect the runtime in any significant way if they are enabled.
     45 static const jvmtiCapabilities standard_caps = {
     46     .can_tag_objects                                 = 1,
     47     .can_generate_field_modification_events          = 1,
     48     .can_generate_field_access_events                = 1,
     49     .can_get_bytecodes                               = 1,
     50     .can_get_synthetic_attribute                     = 1,
     51     .can_get_owned_monitor_info                      = 0,
     52     .can_get_current_contended_monitor               = 1,
     53     .can_get_monitor_info                            = 1,
     54     .can_pop_frame                                   = 0,
     55     .can_redefine_classes                            = 1,
     56     .can_signal_thread                               = 1,
     57     .can_get_source_file_name                        = 1,
     58     .can_get_line_numbers                            = 1,
     59     .can_get_source_debug_extension                  = 1,
     60     .can_access_local_variables                      = 0,
     61     .can_maintain_original_method_order              = 1,
     62     .can_generate_single_step_events                 = 1,
     63     .can_generate_exception_events                   = 0,
     64     .can_generate_frame_pop_events                   = 0,
     65     .can_generate_breakpoint_events                  = 1,
     66     .can_suspend                                     = 1,
     67     .can_redefine_any_class                          = 0,
     68     .can_get_current_thread_cpu_time                 = 0,
     69     .can_get_thread_cpu_time                         = 0,
     70     .can_generate_method_entry_events                = 1,
     71     .can_generate_method_exit_events                 = 1,
     72     .can_generate_all_class_hook_events              = 0,
     73     .can_generate_compiled_method_load_events        = 0,
     74     .can_generate_monitor_events                     = 0,
     75     .can_generate_vm_object_alloc_events             = 1,
     76     .can_generate_native_method_bind_events          = 1,
     77     .can_generate_garbage_collection_events          = 1,
     78     .can_generate_object_free_events                 = 1,
     79     .can_force_early_return                          = 0,
     80     .can_get_owned_monitor_stack_depth_info          = 0,
     81     .can_get_constant_pool                           = 0,
     82     .can_set_native_method_prefix                    = 0,
     83     .can_retransform_classes                         = 1,
     84     .can_retransform_any_class                       = 0,
     85     .can_generate_resource_exhaustion_heap_events    = 0,
     86     .can_generate_resource_exhaustion_threads_events = 0,
     87 };
     88 
     89 jvmtiCapabilities GetStandardCapabilities() {
     90   return standard_caps;
     91 }
     92 
     93 void SetStandardCapabilities(jvmtiEnv* env) {
     94   if (IsJVM()) {
     95     // RI is more strict about adding capabilities at runtime then ART so just give it everything.
     96     SetAllCapabilities(env);
     97     return;
     98   }
     99   jvmtiCapabilities caps = GetStandardCapabilities();
    100   CheckJvmtiError(env, env->AddCapabilities(&caps));
    101 }
    102 
    103 void SetAllCapabilities(jvmtiEnv* env) {
    104   jvmtiCapabilities caps;
    105   CheckJvmtiError(env, env->GetPotentialCapabilities(&caps));
    106   CheckJvmtiError(env, env->AddCapabilities(&caps));
    107 }
    108 
    109 bool JvmtiErrorToException(JNIEnv* env, jvmtiEnv* jvmtienv, jvmtiError error) {
    110   if (error == JVMTI_ERROR_NONE) {
    111     return false;
    112   }
    113 
    114   ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
    115   if (rt_exception.get() == nullptr) {
    116     // CNFE should be pending.
    117     return true;
    118   }
    119 
    120   char* err;
    121   CheckJvmtiError(jvmtienv, jvmtienv->GetErrorName(error, &err));
    122 
    123   env->ThrowNew(rt_exception.get(), err);
    124 
    125   Deallocate(jvmtienv, err);
    126   return true;
    127 }
    128 
    129 std::ostream& operator<<(std::ostream& os, const jvmtiError& rhs) {
    130   switch (rhs) {
    131     case JVMTI_ERROR_NONE:
    132       return os << "NONE";
    133     case JVMTI_ERROR_INVALID_THREAD:
    134       return os << "INVALID_THREAD";
    135     case JVMTI_ERROR_INVALID_THREAD_GROUP:
    136       return os << "INVALID_THREAD_GROUP";
    137     case JVMTI_ERROR_INVALID_PRIORITY:
    138       return os << "INVALID_PRIORITY";
    139     case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
    140       return os << "THREAD_NOT_SUSPENDED";
    141     case JVMTI_ERROR_THREAD_SUSPENDED:
    142       return os << "THREAD_SUSPENDED";
    143     case JVMTI_ERROR_THREAD_NOT_ALIVE:
    144       return os << "THREAD_NOT_ALIVE";
    145     case JVMTI_ERROR_INVALID_OBJECT:
    146       return os << "INVALID_OBJECT";
    147     case JVMTI_ERROR_INVALID_CLASS:
    148       return os << "INVALID_CLASS";
    149     case JVMTI_ERROR_CLASS_NOT_PREPARED:
    150       return os << "CLASS_NOT_PREPARED";
    151     case JVMTI_ERROR_INVALID_METHODID:
    152       return os << "INVALID_METHODID";
    153     case JVMTI_ERROR_INVALID_LOCATION:
    154       return os << "INVALID_LOCATION";
    155     case JVMTI_ERROR_INVALID_FIELDID:
    156       return os << "INVALID_FIELDID";
    157     case JVMTI_ERROR_NO_MORE_FRAMES:
    158       return os << "NO_MORE_FRAMES";
    159     case JVMTI_ERROR_OPAQUE_FRAME:
    160       return os << "OPAQUE_FRAME";
    161     case JVMTI_ERROR_TYPE_MISMATCH:
    162       return os << "TYPE_MISMATCH";
    163     case JVMTI_ERROR_INVALID_SLOT:
    164       return os << "INVALID_SLOT";
    165     case JVMTI_ERROR_DUPLICATE:
    166       return os << "DUPLICATE";
    167     case JVMTI_ERROR_NOT_FOUND:
    168       return os << "NOT_FOUND";
    169     case JVMTI_ERROR_INVALID_MONITOR:
    170       return os << "INVALID_MONITOR";
    171     case JVMTI_ERROR_NOT_MONITOR_OWNER:
    172       return os << "NOT_MONITOR_OWNER";
    173     case JVMTI_ERROR_INTERRUPT:
    174       return os << "INTERRUPT";
    175     case JVMTI_ERROR_INVALID_CLASS_FORMAT:
    176       return os << "INVALID_CLASS_FORMAT";
    177     case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
    178       return os << "CIRCULAR_CLASS_DEFINITION";
    179     case JVMTI_ERROR_FAILS_VERIFICATION:
    180       return os << "FAILS_VERIFICATION";
    181     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
    182       return os << "UNSUPPORTED_REDEFINITION_METHOD_ADDED";
    183     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
    184       return os << "UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED";
    185     case JVMTI_ERROR_INVALID_TYPESTATE:
    186       return os << "INVALID_TYPESTATE";
    187     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
    188       return os << "UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED";
    189     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
    190       return os << "UNSUPPORTED_REDEFINITION_METHOD_DELETED";
    191     case JVMTI_ERROR_UNSUPPORTED_VERSION:
    192       return os << "UNSUPPORTED_VERSION";
    193     case JVMTI_ERROR_NAMES_DONT_MATCH:
    194       return os << "NAMES_DONT_MATCH";
    195     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
    196       return os << "UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED";
    197     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
    198       return os << "UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED";
    199     case JVMTI_ERROR_UNMODIFIABLE_CLASS:
    200       return os << "JVMTI_ERROR_UNMODIFIABLE_CLASS";
    201     case JVMTI_ERROR_NOT_AVAILABLE:
    202       return os << "NOT_AVAILABLE";
    203     case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
    204       return os << "MUST_POSSESS_CAPABILITY";
    205     case JVMTI_ERROR_NULL_POINTER:
    206       return os << "NULL_POINTER";
    207     case JVMTI_ERROR_ABSENT_INFORMATION:
    208       return os << "ABSENT_INFORMATION";
    209     case JVMTI_ERROR_INVALID_EVENT_TYPE:
    210       return os << "INVALID_EVENT_TYPE";
    211     case JVMTI_ERROR_ILLEGAL_ARGUMENT:
    212       return os << "ILLEGAL_ARGUMENT";
    213     case JVMTI_ERROR_NATIVE_METHOD:
    214       return os << "NATIVE_METHOD";
    215     case JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED:
    216       return os << "CLASS_LOADER_UNSUPPORTED";
    217     case JVMTI_ERROR_OUT_OF_MEMORY:
    218       return os << "OUT_OF_MEMORY";
    219     case JVMTI_ERROR_ACCESS_DENIED:
    220       return os << "ACCESS_DENIED";
    221     case JVMTI_ERROR_WRONG_PHASE:
    222       return os << "WRONG_PHASE";
    223     case JVMTI_ERROR_INTERNAL:
    224       return os << "INTERNAL";
    225     case JVMTI_ERROR_UNATTACHED_THREAD:
    226       return os << "UNATTACHED_THREAD";
    227     case JVMTI_ERROR_INVALID_ENVIRONMENT:
    228       return os << "INVALID_ENVIRONMENT";
    229   }
    230   LOG(FATAL) << "Unexpected error type " << static_cast<int>(rhs);
    231   __builtin_unreachable();
    232 }
    233 
    234 }  // namespace art
    235