25 #include <stdlib.h> |
25 #include <stdlib.h> |
26 #include <string.h> |
26 #include <string.h> |
27 #include "jvmti.h" |
27 #include "jvmti.h" |
28 #include "agent_common.h" |
28 #include "agent_common.h" |
29 |
29 |
30 #ifdef __cplusplus |
|
31 extern "C" { |
30 extern "C" { |
32 #endif |
|
33 |
|
34 #ifndef JNI_ENV_ARG |
|
35 |
|
36 #ifdef __cplusplus |
|
37 #define JNI_ENV_ARG(x, y) y |
|
38 #define JNI_ENV_ARG1(x) |
|
39 #define JNI_ENV_PTR(x) x |
|
40 #else |
|
41 #define JNI_ENV_ARG(x,y) x, y |
|
42 #define JNI_ENV_ARG1(x) x |
|
43 #define JNI_ENV_PTR(x) (*x) |
|
44 #endif |
|
45 |
|
46 #endif |
|
47 |
|
48 #define JVMTI_ENV_ARG JNI_ENV_ARG |
|
49 #define JVMTI_ENV_ARG1 JNI_ENV_ARG1 |
|
50 #define JVMTI_ENV_PTR JNI_ENV_PTR |
|
51 |
31 |
52 #define JVMTI_ERROR_CHECK(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;} |
32 #define JVMTI_ERROR_CHECK(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;} |
53 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); return res;} |
33 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); return res;} |
54 |
34 |
55 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; } |
35 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; } |
104 vmDeath(jvmtiEnv *jvmti, JNIEnv* jni) { |
84 vmDeath(jvmtiEnv *jvmti, JNIEnv* jni) { |
105 jvmtiError res; |
85 jvmtiError res; |
106 |
86 |
107 debug_printf("VMDeath event done\n"); |
87 debug_printf("VMDeath event done\n"); |
108 |
88 |
109 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment)); |
89 res = jvmti->AddToBootstrapClassLoaderSearch(segment); |
110 /* In the live phase, anything other than an existing JAR file is an invalid path. |
90 /* In the live phase, anything other than an existing JAR file is an invalid path. |
111 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown. |
91 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown. |
112 */ |
92 */ |
113 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMDeath: AddToBootstrapClassLoaderSearch returned error ", |
93 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMDeath: AddToBootstrapClassLoaderSearch returned error ", |
114 res, JVMTI_ERROR_ILLEGAL_ARGUMENT); |
94 res, JVMTI_ERROR_ILLEGAL_ARGUMENT); |
120 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { |
100 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { |
121 jvmtiError res; |
101 jvmtiError res; |
122 |
102 |
123 debug_printf("VMInit event done\n"); |
103 debug_printf("VMInit event done\n"); |
124 |
104 |
125 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment)); |
105 res = jvmti->AddToBootstrapClassLoaderSearch(segment); |
126 /* In the live phase, anything other than an existing JAR file is an invalid path. |
106 /* In the live phase, anything other than an existing JAR file is an invalid path. |
127 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown. |
107 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown. |
128 */ |
108 */ |
129 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMInit: AddToBootstrapClassLoaderSearch returned error ", |
109 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMInit: AddToBootstrapClassLoaderSearch returned error ", |
130 res, JVMTI_ERROR_ILLEGAL_ARGUMENT); |
110 res, JVMTI_ERROR_ILLEGAL_ARGUMENT); |
138 jthread thread, jmethodID method, |
118 jthread thread, jmethodID method, |
139 void* address, void** new_address_ptr) { |
119 void* address, void** new_address_ptr) { |
140 jvmtiPhase phase; |
120 jvmtiPhase phase; |
141 jvmtiError res; |
121 jvmtiError res; |
142 |
122 |
143 res = JVMTI_ENV_PTR(jvmti)->GetPhase(JVMTI_ENV_ARG(jvmti, &phase)); |
123 res = jvmti->GetPhase(&phase); |
144 JVMTI_ERROR_CHECK_VOID("GetPhase returned error", res); |
124 JVMTI_ERROR_CHECK_VOID("GetPhase returned error", res); |
145 |
125 |
146 if (phase == JVMTI_PHASE_PRIMORDIAL) { |
126 if (phase == JVMTI_PHASE_PRIMORDIAL) { |
147 debug_printf("Primordial phase\n"); |
127 debug_printf("Primordial phase\n"); |
148 |
128 |
149 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment)); |
129 res = jvmti->AddToBootstrapClassLoaderSearch(segment); |
150 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("Primordial: AddToBootstrapClassLoaderSearch returned error ", |
130 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("Primordial: AddToBootstrapClassLoaderSearch returned error ", |
151 res, JVMTI_ERROR_WRONG_PHASE); |
131 res, JVMTI_ERROR_WRONG_PHASE); |
152 } |
132 } |
153 } |
133 } |
154 |
134 |
213 segment[(size_t) sizeof(segment)/sizeof(char) - 1] = 0; |
193 segment[(size_t) sizeof(segment)/sizeof(char) - 1] = 0; |
214 idx = strchr(segment, ','); |
194 idx = strchr(segment, ','); |
215 if (idx != NULL) *idx = 0; |
195 if (idx != NULL) *idx = 0; |
216 } |
196 } |
217 |
197 |
218 res = JNI_ENV_PTR(jvm)-> |
198 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1); |
219 GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_1_1); |
|
220 if (res < 0) { |
199 if (res < 0) { |
221 printf("Wrong result of a valid call to GetEnv!\n"); |
200 printf("Wrong result of a valid call to GetEnv!\n"); |
222 return JNI_ERR; |
201 return JNI_ERR; |
223 } |
202 } |
224 |
203 |
225 /* Add capabilities */ |
204 /* Add capabilities */ |
226 res = JVMTI_ENV_PTR(jvmti)->GetPotentialCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps)); |
205 res = jvmti->GetPotentialCapabilities(&jvmti_caps); |
227 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res); |
206 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res); |
228 |
207 |
229 res = JVMTI_ENV_PTR(jvmti)->AddCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps)); |
208 res = jvmti->AddCapabilities(&jvmti_caps); |
230 JVMTI_ERROR_CHECK("GetAddCapabilities returned error", res); |
209 JVMTI_ERROR_CHECK("GetAddCapabilities returned error", res); |
231 |
210 |
232 |
211 |
233 /* Enable events */ |
212 /* Enable events */ |
234 init_callbacks(); |
213 init_callbacks(); |
235 res = JVMTI_ENV_PTR(jvmti)->SetEventCallbacks(JVMTI_ENV_ARG(jvmti, &callbacks), sizeof(callbacks)); |
214 res = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); |
236 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res); |
215 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res); |
237 |
216 |
238 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_START,NULL); |
217 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); |
239 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_START returned error", res); |
218 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_START returned error", res); |
240 |
219 |
241 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_INIT,NULL); |
220 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL); |
242 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res); |
221 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res); |
243 |
222 |
244 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_NATIVE_METHOD_BIND,NULL); |
223 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL); |
245 JVMTI_ERROR_CHECK("SetEventNotificationMode for NATIVE_METHOD_BIND returned error", res); |
224 JVMTI_ERROR_CHECK("SetEventNotificationMode for NATIVE_METHOD_BIND returned error", res); |
246 |
225 |
247 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_DEATH,NULL); |
226 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL); |
248 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_DEATH returned error", res); |
227 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_DEATH returned error", res); |
249 |
228 |
250 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,NULL); |
229 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL); |
251 JVMTI_ERROR_CHECK("SetEventNotificationMode CLASS_FILE_LOAD_HOOK returned error", res); |
230 JVMTI_ERROR_CHECK("SetEventNotificationMode CLASS_FILE_LOAD_HOOK returned error", res); |
252 |
231 |
253 strcat(segment, "/newclass"); |
232 strcat(segment, "/newclass"); |
254 debug_printf("segment=%s\n", segment); |
233 debug_printf("segment=%s\n", segment); |
255 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment)); |
234 res = jvmti->AddToBootstrapClassLoaderSearch(segment); |
256 JVMTI_ERROR_CHECK("AddToBootStrapClassLoaderSearch returned error", res); |
235 JVMTI_ERROR_CHECK("AddToBootStrapClassLoaderSearch returned error", res); |
257 |
236 |
258 return JNI_OK; |
237 return JNI_OK; |
259 } |
238 } |
260 |
239 |