blob: bceaa6b64ba399909b27fc5776cd0085c699ff08 [file] [log] [blame]
Andreas Gampe3f46c962017-03-30 10:26:59 -07001/*
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"
Alex Light47d49b82017-07-25 14:06:34 -070018#include "test_env.h"
Andreas Gampe3f46c962017-03-30 10:26:59 -070019
Andreas Gampe3f46c962017-03-30 10:26:59 -070020#include <dlfcn.h>
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070021
22#include <algorithm>
23#include <cstdio>
24#include <cstring>
Andreas Gampe3f46c962017-03-30 10:26:59 -070025#include <sstream>
Andreas Gampe3f46c962017-03-30 10:26:59 -070026
27#include "android-base/logging.h"
28#include "scoped_local_ref.h"
29
30namespace art {
31
32void 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
Alex Light3d324fd2017-07-20 15:38:52 -070043// 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.
45static 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,
Alex Light41006c62017-09-14 09:51:14 -070052 .can_get_current_contended_monitor = 1,
Alex Lightce568642017-09-05 16:54:25 -070053 .can_get_monitor_info = 1,
Alex Light3d324fd2017-07-20 15:38:52 -070054 .can_pop_frame = 0,
55 .can_redefine_classes = 1,
Alex Light54d39dc2017-09-25 17:00:16 -070056 .can_signal_thread = 1,
Alex Light3d324fd2017-07-20 15:38:52 -070057 .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,
Alex Lightb566fed2017-07-28 15:17:00 -070061 .can_maintain_original_method_order = 1,
Alex Light3d324fd2017-07-20 15:38:52 -070062 .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
89jvmtiCapabilities GetStandardCapabilities() {
90 return standard_caps;
91}
92
93void SetStandardCapabilities(jvmtiEnv* env) {
Alex Light47d49b82017-07-25 14:06:34 -070094 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 }
Alex Light3d324fd2017-07-20 15:38:52 -070099 jvmtiCapabilities caps = GetStandardCapabilities();
100 CheckJvmtiError(env, env->AddCapabilities(&caps));
101}
102
Andreas Gampe3f46c962017-03-30 10:26:59 -0700103void SetAllCapabilities(jvmtiEnv* env) {
104 jvmtiCapabilities caps;
Alex Light3d324fd2017-07-20 15:38:52 -0700105 CheckJvmtiError(env, env->GetPotentialCapabilities(&caps));
106 CheckJvmtiError(env, env->AddCapabilities(&caps));
Andreas Gampe3f46c962017-03-30 10:26:59 -0700107}
108
Alex Light47d49b82017-07-25 14:06:34 -0700109bool JvmtiErrorToException(JNIEnv* env, jvmtiEnv* jvmtienv, jvmtiError error) {
Andreas Gampe3f46c962017-03-30 10:26:59 -0700110 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;
Alex Light47d49b82017-07-25 14:06:34 -0700121 CheckJvmtiError(jvmtienv, jvmtienv->GetErrorName(error, &err));
Andreas Gampe3f46c962017-03-30 10:26:59 -0700122
123 env->ThrowNew(rt_exception.get(), err);
124
Alex Light47d49b82017-07-25 14:06:34 -0700125 Deallocate(jvmtienv, err);
Andreas Gampe3f46c962017-03-30 10:26:59 -0700126 return true;
127}
128
129std::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