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 
CheckJvmtiError(jvmtiEnv * env,jvmtiError error)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 
GetStandardCapabilities()89 jvmtiCapabilities GetStandardCapabilities() {
90   return standard_caps;
91 }
92 
SetStandardCapabilities(jvmtiEnv * env)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 
SetAllCapabilities(jvmtiEnv * env)103 void SetAllCapabilities(jvmtiEnv* env) {
104   jvmtiCapabilities caps;
105   CheckJvmtiError(env, env->GetPotentialCapabilities(&caps));
106   CheckJvmtiError(env, env->AddCapabilities(&caps));
107 }
108 
JvmtiErrorToException(JNIEnv * env,jvmtiEnv * jvmtienv,jvmtiError error)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 
operator <<(std::ostream & os,const jvmtiError & rhs)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