10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "jvmti.h"
28 #include "agent_common.h"
29
30 #ifdef __cplusplus
31 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
52 #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;}
54
55 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
56
57 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); iGlobalStatus = 2; }
58
59 static jvmtiEnv *jvmti;
60 static jint iGlobalStatus = 0;
61 static jvmtiCapabilities jvmti_caps;
62 static jvmtiEventCallbacks callbacks;
63 static int boot_class_count = 0;
64
65 static const char* BOOT_CLASS =
66 "nsk/jvmti/unit/functions/AddToBootstrapClassLoaderSearch/Boot";
67
68 static const char* CLASSPATH = "java.class.path";
69
70 static char segment[3000] = ".";
75 void debug_printf(const char *fmt, ...) {
76 va_list args;
77
78 va_start(args, fmt);
79 if (printdump) {
80 vprintf(fmt, args);
81 }
82 va_end(args);
83 }
84
85
86 /*
87 * Check that it is not possible to add to the boot class path during the Start phase
88 */
89 void JNICALL
90 vmStart(jvmtiEnv *jvmti, JNIEnv* jni) {
91 jvmtiError res;
92
93 debug_printf("VMStart event done\n");
94
95 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment));
96 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMStart: AddToBootstrapClassLoaderSearch returned error ",
97 res, JVMTI_ERROR_WRONG_PHASE);
98 }
99
100 /*
101 * Check that it is possible to add to the boot class path before VMDeath event return.
102 */
103 void JNICALL
104 vmDeath(jvmtiEnv *jvmti, JNIEnv* jni) {
105 jvmtiError res;
106
107 debug_printf("VMDeath event done\n");
108
109 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment));
110 /* 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.
112 */
113 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMDeath: AddToBootstrapClassLoaderSearch returned error ",
114 res, JVMTI_ERROR_ILLEGAL_ARGUMENT);
115 }
116
117 /*
118 * Check that it is possible to add to the boot class path during the Live phase
119 */
120 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) {
121 jvmtiError res;
122
123 debug_printf("VMInit event done\n");
124
125 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment));
126 /* 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.
128 */
129 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMInit: AddToBootstrapClassLoaderSearch returned error ",
130 res, JVMTI_ERROR_ILLEGAL_ARGUMENT);
131 }
132
133 /*
134 * Check that it is not possible to add to the boot class path during the Primordial phase
135 */
136 void JNICALL
137 NativeMethodBind(jvmtiEnv* jvmti, JNIEnv *jni,
138 jthread thread, jmethodID method,
139 void* address, void** new_address_ptr) {
140 jvmtiPhase phase;
141 jvmtiError res;
142
143 res = JVMTI_ENV_PTR(jvmti)->GetPhase(JVMTI_ENV_ARG(jvmti, &phase));
144 JVMTI_ERROR_CHECK_VOID("GetPhase returned error", res);
145
146 if (phase == JVMTI_PHASE_PRIMORDIAL) {
147 debug_printf("Primordial phase\n");
148
149 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment));
150 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("Primordial: AddToBootstrapClassLoaderSearch returned error ",
151 res, JVMTI_ERROR_WRONG_PHASE);
152 }
153 }
154
155
156 void JNICALL
157 classFileLoadEvent(jvmtiEnv *jvmti_env, JNIEnv *env,
158 jclass redefined_class,
159 jobject loader,const char* name,
160 jobject protection_domain,
161 jint class_data_len,
162 const unsigned char* class_data,
163 jint* new_class_data_len,
164 unsigned char** new_class_data) {
165
166 if (name != NULL && (strcmp(name, BOOT_CLASS) == 0)) {
167 debug_printf("Received class file load hook event for class: \n\t%s\n",
168 name);
169 debug_printf("Received class loader: 0x%p \n", loader);
198 return JNI_VERSION_1_8;
199 }
200 #endif
201 jint Agent_Initialize(JavaVM * jvm, char *options, void *reserved) {
202 jint res;
203 char *idx;
204
205 debug_printf("Agent_OnLoad event done\n");
206
207 if (options && strlen(options) > 0) {
208 if (strstr(options, "printdump")) {
209 printdump = 1;
210 }
211
212 strncpy(segment, options, (size_t) sizeof(segment)/sizeof(char));
213 segment[(size_t) sizeof(segment)/sizeof(char) - 1] = 0;
214 idx = strchr(segment, ',');
215 if (idx != NULL) *idx = 0;
216 }
217
218 res = JNI_ENV_PTR(jvm)->
219 GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_1_1);
220 if (res < 0) {
221 printf("Wrong result of a valid call to GetEnv!\n");
222 return JNI_ERR;
223 }
224
225 /* Add capabilities */
226 res = JVMTI_ENV_PTR(jvmti)->GetPotentialCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps));
227 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res);
228
229 res = JVMTI_ENV_PTR(jvmti)->AddCapabilities(JVMTI_ENV_ARG(jvmti, &jvmti_caps));
230 JVMTI_ERROR_CHECK("GetAddCapabilities returned error", res);
231
232
233 /* Enable events */
234 init_callbacks();
235 res = JVMTI_ENV_PTR(jvmti)->SetEventCallbacks(JVMTI_ENV_ARG(jvmti, &callbacks), sizeof(callbacks));
236 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res);
237
238 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_START,NULL);
239 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_START returned error", res);
240
241 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_INIT,NULL);
242 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res);
243
244 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_NATIVE_METHOD_BIND,NULL);
245 JVMTI_ERROR_CHECK("SetEventNotificationMode for NATIVE_METHOD_BIND returned error", res);
246
247 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_VM_DEATH,NULL);
248 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_DEATH returned error", res);
249
250 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti,JVMTI_ENABLE),JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,NULL);
251 JVMTI_ERROR_CHECK("SetEventNotificationMode CLASS_FILE_LOAD_HOOK returned error", res);
252
253 strcat(segment, "/newclass");
254 debug_printf("segment=%s\n", segment);
255 res = JVMTI_ENV_PTR(jvmti)->AddToBootstrapClassLoaderSearch(JVMTI_ENV_ARG(jvmti, segment));
256 JVMTI_ERROR_CHECK("AddToBootStrapClassLoaderSearch returned error", res);
257
258 return JNI_OK;
259 }
260
261 JNIEXPORT jint JNICALL
262 Java_nsk_jvmti_unit_functions_AddToBootstrapClassLoaderSearch_JvmtiTest_GetResult(JNIEnv * env, jclass cls) {
263
264 if (boot_class_count != 1) {
265 printf("Error: no ClassFileLoadHook event for Boot class loaded from bootstrap class path\n");
266 iGlobalStatus = 2;
267 }
268 return iGlobalStatus;
269 }
270
271
272 #ifdef __cplusplus
273 }
274 #endif
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "jvmti.h"
28 #include "agent_common.h"
29
30 extern "C" {
31
32 #define JVMTI_ERROR_CHECK(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%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;}
34
35 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
36
37 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); iGlobalStatus = 2; }
38
39 static jvmtiEnv *jvmti;
40 static jint iGlobalStatus = 0;
41 static jvmtiCapabilities jvmti_caps;
42 static jvmtiEventCallbacks callbacks;
43 static int boot_class_count = 0;
44
45 static const char* BOOT_CLASS =
46 "nsk/jvmti/unit/functions/AddToBootstrapClassLoaderSearch/Boot";
47
48 static const char* CLASSPATH = "java.class.path";
49
50 static char segment[3000] = ".";
55 void debug_printf(const char *fmt, ...) {
56 va_list args;
57
58 va_start(args, fmt);
59 if (printdump) {
60 vprintf(fmt, args);
61 }
62 va_end(args);
63 }
64
65
66 /*
67 * Check that it is not possible to add to the boot class path during the Start phase
68 */
69 void JNICALL
70 vmStart(jvmtiEnv *jvmti, JNIEnv* jni) {
71 jvmtiError res;
72
73 debug_printf("VMStart event done\n");
74
75 res = jvmti->AddToBootstrapClassLoaderSearch(segment);
76 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMStart: AddToBootstrapClassLoaderSearch returned error ",
77 res, JVMTI_ERROR_WRONG_PHASE);
78 }
79
80 /*
81 * Check that it is possible to add to the boot class path before VMDeath event return.
82 */
83 void JNICALL
84 vmDeath(jvmtiEnv *jvmti, JNIEnv* jni) {
85 jvmtiError res;
86
87 debug_printf("VMDeath event done\n");
88
89 res = jvmti->AddToBootstrapClassLoaderSearch(segment);
90 /* In the live phase, anything other than an existing JAR file is an invalid path.
91 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown.
92 */
93 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMDeath: AddToBootstrapClassLoaderSearch returned error ",
94 res, JVMTI_ERROR_ILLEGAL_ARGUMENT);
95 }
96
97 /*
98 * Check that it is possible to add to the boot class path during the Live phase
99 */
100 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) {
101 jvmtiError res;
102
103 debug_printf("VMInit event done\n");
104
105 res = jvmti->AddToBootstrapClassLoaderSearch(segment);
106 /* In the live phase, anything other than an existing JAR file is an invalid path.
107 So, check that JVMTI_ERROR_ILLEGAL_ARGUMENT error is thrown.
108 */
109 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("VMInit: AddToBootstrapClassLoaderSearch returned error ",
110 res, JVMTI_ERROR_ILLEGAL_ARGUMENT);
111 }
112
113 /*
114 * Check that it is not possible to add to the boot class path during the Primordial phase
115 */
116 void JNICALL
117 NativeMethodBind(jvmtiEnv* jvmti, JNIEnv *jni,
118 jthread thread, jmethodID method,
119 void* address, void** new_address_ptr) {
120 jvmtiPhase phase;
121 jvmtiError res;
122
123 res = jvmti->GetPhase(&phase);
124 JVMTI_ERROR_CHECK_VOID("GetPhase returned error", res);
125
126 if (phase == JVMTI_PHASE_PRIMORDIAL) {
127 debug_printf("Primordial phase\n");
128
129 res = jvmti->AddToBootstrapClassLoaderSearch(segment);
130 JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID("Primordial: AddToBootstrapClassLoaderSearch returned error ",
131 res, JVMTI_ERROR_WRONG_PHASE);
132 }
133 }
134
135
136 void JNICALL
137 classFileLoadEvent(jvmtiEnv *jvmti_env, JNIEnv *env,
138 jclass redefined_class,
139 jobject loader,const char* name,
140 jobject protection_domain,
141 jint class_data_len,
142 const unsigned char* class_data,
143 jint* new_class_data_len,
144 unsigned char** new_class_data) {
145
146 if (name != NULL && (strcmp(name, BOOT_CLASS) == 0)) {
147 debug_printf("Received class file load hook event for class: \n\t%s\n",
148 name);
149 debug_printf("Received class loader: 0x%p \n", loader);
178 return JNI_VERSION_1_8;
179 }
180 #endif
181 jint Agent_Initialize(JavaVM * jvm, char *options, void *reserved) {
182 jint res;
183 char *idx;
184
185 debug_printf("Agent_OnLoad event done\n");
186
187 if (options && strlen(options) > 0) {
188 if (strstr(options, "printdump")) {
189 printdump = 1;
190 }
191
192 strncpy(segment, options, (size_t) sizeof(segment)/sizeof(char));
193 segment[(size_t) sizeof(segment)/sizeof(char) - 1] = 0;
194 idx = strchr(segment, ',');
195 if (idx != NULL) *idx = 0;
196 }
197
198 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
199 if (res < 0) {
200 printf("Wrong result of a valid call to GetEnv!\n");
201 return JNI_ERR;
202 }
203
204 /* Add capabilities */
205 res = jvmti->GetPotentialCapabilities(&jvmti_caps);
206 JVMTI_ERROR_CHECK("GetPotentialCapabilities returned error", res);
207
208 res = jvmti->AddCapabilities(&jvmti_caps);
209 JVMTI_ERROR_CHECK("GetAddCapabilities returned error", res);
210
211
212 /* Enable events */
213 init_callbacks();
214 res = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
215 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res);
216
217 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL);
218 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_START returned error", res);
219
220 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
221 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res);
222
223 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL);
224 JVMTI_ERROR_CHECK("SetEventNotificationMode for NATIVE_METHOD_BIND returned error", res);
225
226 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
227 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_DEATH returned error", res);
228
229 res = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
230 JVMTI_ERROR_CHECK("SetEventNotificationMode CLASS_FILE_LOAD_HOOK returned error", res);
231
232 strcat(segment, "/newclass");
233 debug_printf("segment=%s\n", segment);
234 res = jvmti->AddToBootstrapClassLoaderSearch(segment);
235 JVMTI_ERROR_CHECK("AddToBootStrapClassLoaderSearch returned error", res);
236
237 return JNI_OK;
238 }
239
240 JNIEXPORT jint JNICALL
241 Java_nsk_jvmti_unit_functions_AddToBootstrapClassLoaderSearch_JvmtiTest_GetResult(JNIEnv * env, jclass cls) {
242
243 if (boot_class_count != 1) {
244 printf("Error: no ClassFileLoadHook event for Boot class loaded from bootstrap class path\n");
245 iGlobalStatus = 2;
246 }
247 return iGlobalStatus;
248 }
249
250
251 }
|