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 
19 #include <algorithm>
20 #include <dlfcn.h>
21 #include <stdio.h>
22 #include <sstream>
23 #include <string.h>
24 
25 #include "android-base/logging.h"
26 #include "scoped_local_ref.h"
27 
28 namespace art {
29 
CheckJvmtiError(jvmtiEnv * env,jvmtiError error)30 void CheckJvmtiError(jvmtiEnv* env, jvmtiError error) {
31   if (error != JVMTI_ERROR_NONE) {
32     char* error_name;
33     jvmtiError name_error = env->GetErrorName(error, &error_name);
34     if (name_error != JVMTI_ERROR_NONE) {
35       LOG(FATAL) << "Unable to get error name for " << error;
36     }
37     LOG(FATAL) << "Unexpected error: " << error_name;
38   }
39 }
40 
SetAllCapabilities(jvmtiEnv * env)41 void SetAllCapabilities(jvmtiEnv* env) {
42   jvmtiCapabilities caps;
43   jvmtiError error1 = env->GetPotentialCapabilities(&caps);
44   CheckJvmtiError(env, error1);
45   jvmtiError error2 = env->AddCapabilities(&caps);
46   CheckJvmtiError(env, error2);
47 }
48 
JvmtiErrorToException(JNIEnv * env,jvmtiEnv * jvmti_env,jvmtiError error)49 bool JvmtiErrorToException(JNIEnv* env, jvmtiEnv* jvmti_env, jvmtiError error) {
50   if (error == JVMTI_ERROR_NONE) {
51     return false;
52   }
53 
54   ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
55   if (rt_exception.get() == nullptr) {
56     // CNFE should be pending.
57     return true;
58   }
59 
60   char* err;
61   CheckJvmtiError(jvmti_env, jvmti_env->GetErrorName(error, &err));
62 
63   env->ThrowNew(rt_exception.get(), err);
64 
65   Deallocate(jvmti_env, err);
66   return true;
67 }
68 
operator <<(std::ostream & os,const jvmtiError & rhs)69 std::ostream& operator<<(std::ostream& os, const jvmtiError& rhs) {
70   switch (rhs) {
71     case JVMTI_ERROR_NONE:
72       return os << "NONE";
73     case JVMTI_ERROR_INVALID_THREAD:
74       return os << "INVALID_THREAD";
75     case JVMTI_ERROR_INVALID_THREAD_GROUP:
76       return os << "INVALID_THREAD_GROUP";
77     case JVMTI_ERROR_INVALID_PRIORITY:
78       return os << "INVALID_PRIORITY";
79     case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
80       return os << "THREAD_NOT_SUSPENDED";
81     case JVMTI_ERROR_THREAD_SUSPENDED:
82       return os << "THREAD_SUSPENDED";
83     case JVMTI_ERROR_THREAD_NOT_ALIVE:
84       return os << "THREAD_NOT_ALIVE";
85     case JVMTI_ERROR_INVALID_OBJECT:
86       return os << "INVALID_OBJECT";
87     case JVMTI_ERROR_INVALID_CLASS:
88       return os << "INVALID_CLASS";
89     case JVMTI_ERROR_CLASS_NOT_PREPARED:
90       return os << "CLASS_NOT_PREPARED";
91     case JVMTI_ERROR_INVALID_METHODID:
92       return os << "INVALID_METHODID";
93     case JVMTI_ERROR_INVALID_LOCATION:
94       return os << "INVALID_LOCATION";
95     case JVMTI_ERROR_INVALID_FIELDID:
96       return os << "INVALID_FIELDID";
97     case JVMTI_ERROR_NO_MORE_FRAMES:
98       return os << "NO_MORE_FRAMES";
99     case JVMTI_ERROR_OPAQUE_FRAME:
100       return os << "OPAQUE_FRAME";
101     case JVMTI_ERROR_TYPE_MISMATCH:
102       return os << "TYPE_MISMATCH";
103     case JVMTI_ERROR_INVALID_SLOT:
104       return os << "INVALID_SLOT";
105     case JVMTI_ERROR_DUPLICATE:
106       return os << "DUPLICATE";
107     case JVMTI_ERROR_NOT_FOUND:
108       return os << "NOT_FOUND";
109     case JVMTI_ERROR_INVALID_MONITOR:
110       return os << "INVALID_MONITOR";
111     case JVMTI_ERROR_NOT_MONITOR_OWNER:
112       return os << "NOT_MONITOR_OWNER";
113     case JVMTI_ERROR_INTERRUPT:
114       return os << "INTERRUPT";
115     case JVMTI_ERROR_INVALID_CLASS_FORMAT:
116       return os << "INVALID_CLASS_FORMAT";
117     case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
118       return os << "CIRCULAR_CLASS_DEFINITION";
119     case JVMTI_ERROR_FAILS_VERIFICATION:
120       return os << "FAILS_VERIFICATION";
121     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
122       return os << "UNSUPPORTED_REDEFINITION_METHOD_ADDED";
123     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
124       return os << "UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED";
125     case JVMTI_ERROR_INVALID_TYPESTATE:
126       return os << "INVALID_TYPESTATE";
127     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
128       return os << "UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED";
129     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
130       return os << "UNSUPPORTED_REDEFINITION_METHOD_DELETED";
131     case JVMTI_ERROR_UNSUPPORTED_VERSION:
132       return os << "UNSUPPORTED_VERSION";
133     case JVMTI_ERROR_NAMES_DONT_MATCH:
134       return os << "NAMES_DONT_MATCH";
135     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
136       return os << "UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED";
137     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
138       return os << "UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED";
139     case JVMTI_ERROR_UNMODIFIABLE_CLASS:
140       return os << "JVMTI_ERROR_UNMODIFIABLE_CLASS";
141     case JVMTI_ERROR_NOT_AVAILABLE:
142       return os << "NOT_AVAILABLE";
143     case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
144       return os << "MUST_POSSESS_CAPABILITY";
145     case JVMTI_ERROR_NULL_POINTER:
146       return os << "NULL_POINTER";
147     case JVMTI_ERROR_ABSENT_INFORMATION:
148       return os << "ABSENT_INFORMATION";
149     case JVMTI_ERROR_INVALID_EVENT_TYPE:
150       return os << "INVALID_EVENT_TYPE";
151     case JVMTI_ERROR_ILLEGAL_ARGUMENT:
152       return os << "ILLEGAL_ARGUMENT";
153     case JVMTI_ERROR_NATIVE_METHOD:
154       return os << "NATIVE_METHOD";
155     case JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED:
156       return os << "CLASS_LOADER_UNSUPPORTED";
157     case JVMTI_ERROR_OUT_OF_MEMORY:
158       return os << "OUT_OF_MEMORY";
159     case JVMTI_ERROR_ACCESS_DENIED:
160       return os << "ACCESS_DENIED";
161     case JVMTI_ERROR_WRONG_PHASE:
162       return os << "WRONG_PHASE";
163     case JVMTI_ERROR_INTERNAL:
164       return os << "INTERNAL";
165     case JVMTI_ERROR_UNATTACHED_THREAD:
166       return os << "UNATTACHED_THREAD";
167     case JVMTI_ERROR_INVALID_ENVIRONMENT:
168       return os << "INVALID_ENVIRONMENT";
169   }
170   LOG(FATAL) << "Unexpected error type " << static_cast<int>(rhs);
171   __builtin_unreachable();
172 }
173 
174 }  // namespace art
175