1 /*
2 * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
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 <string.h>
25 #include "jvmti.h"
26 #include "agent_common.h"
27 #include "jni_tools.h"
28 #include "jvmti_tools.h"
29 #include "JVMTITools.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /* ============================================================================= */
36
37 /* scaffold objects */
38 static jvmtiEnv *jvmti = NULL;
39 static jlong timeout = 0;
40 static jrawMonitorID syncLock = NULL;
41
42 /* constant names */
43 #define STEP_NUMBER 3
44 #define OBJECT_NUMBER 100
45 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1)
46
47 static int eventCount[JVMTI_EVENT_COUNT];
48 static int newEventCount[JVMTI_EVENT_COUNT];
49
50 /* ============================================================================= */
51
52
53 /*
54 * Class: nsk_jvmti_scenarios_events_EM02_em02t006
55 * Method: setTag
56 * Signature: (Ljava/lang/Object;J)Z
57 */
58 JNIEXPORT jboolean JNICALL
Java_nsk_jvmti_scenarios_events_EM02_em02t006_setTag(JNIEnv * env,jobject this,jobject object,jlong tag)59 Java_nsk_jvmti_scenarios_events_EM02_em02t006_setTag(JNIEnv *env,
60 jobject this, jobject object, jlong tag) {
61
62 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, object, tag))) {
63 NSK_COMPLAIN0("TEST FAILED: unable to set tag for a tested object\n");
64 return NSK_FALSE;
65 }
66 return NSK_TRUE;
67 }
68
69 static void
showEventStatistics(int step)70 showEventStatistics(int step) {
71 int i;
72 const char* str;
73 int *currentCounts = (step == 1) ? &eventCount[0] : &newEventCount[0];
74
75 NSK_DISPLAY0("\n");
76 NSK_DISPLAY1("Event statistics for %d step:\n", step);
77 NSK_DISPLAY0("-----------------------------\n");
78 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
79 if (currentCounts[i] > 0) {
80 str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL));
81 NSK_DISPLAY2("%-40s %7d\n", str, currentCounts[i]);
82 }
83 }
84 }
85
86 /* ========================================================================== */
87
checkEvents(int step)88 int checkEvents(int step) {
89 int i;
90 jvmtiEvent curr;
91 int result = NSK_TRUE;
92 int *currentCounts;
93 int isExpected = 0;
94
95 switch (step) {
96 case 1:
97 currentCounts = &eventCount[0];
98 break;
99
100 case 2:
101 case 3:
102 currentCounts = &newEventCount[0];
103 break;
104
105 default:
106 NSK_COMPLAIN1("Unexpected step no: %d\n", step);
107 return NSK_FALSE;
108 }
109
110 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
111
112 curr = i + JVMTI_MIN_EVENT_TYPE_VAL;
113
114 switch (step) {
115 case 1:
116 isExpected = ((curr == JVMTI_EVENT_OBJECT_FREE)
117 || (curr == JVMTI_EVENT_VM_INIT));
118 break;
119
120 case 2:
121 isExpected = (curr == JVMTI_EVENT_OBJECT_FREE);
122 break;
123
124 case 3:
125 isExpected = (curr == JVMTI_EVENT_VM_DEATH);
126 break;
127 }
128
129 if (isExpected) {
130 if (currentCounts[i] < 0 || currentCounts[i] > OBJECT_NUMBER) {
131 NSK_COMPLAIN2("Unexpected events number %7d for %s\n\texpected value must be greater than 1\n",
132 currentCounts[i],
133 TranslateEvent(curr));
134 result = NSK_FALSE;
135 }
136 } else {
137
138 if (currentCounts[i] > 0) {
139 NSK_COMPLAIN2("Unexpected event %s was sent %d times\n",
140 TranslateEvent(curr),
141 currentCounts[i]);
142 result = NSK_FALSE;
143 }
144 }
145 }
146
147 return result;
148 }
149
150 static void
changeCount(jvmtiEvent event,int * currentCounts)151 changeCount(jvmtiEvent event, int *currentCounts) {
152
153 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, syncLock)))
154 nsk_jvmti_setFailStatus();
155
156 currentCounts[event - JVMTI_MIN_EVENT_TYPE_VAL]++;
157
158 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, syncLock)))
159 nsk_jvmti_setFailStatus();
160
161 }
162
163 /* ============================================================================= */
164
165 /* callbacks */
166 JNIEXPORT void JNICALL
cbVMInit(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread)167 cbVMInit(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread) {
168 changeCount(JVMTI_EVENT_VM_INIT, &eventCount[0]);
169 }
170
171 JNIEXPORT void JNICALL
cbVMDeath(jvmtiEnv * jvmti,JNIEnv * jni_env)172 cbVMDeath(jvmtiEnv* jvmti, JNIEnv* jni_env) {
173 changeCount(JVMTI_EVENT_VM_DEATH, &newEventCount[0]);
174 showEventStatistics(STEP_NUMBER);
175 if (!checkEvents(STEP_NUMBER))
176 nsk_jvmti_setFailStatus();
177
178 if (!NSK_JVMTI_VERIFY(
179 NSK_CPP_STUB2(DestroyRawMonitor, jvmti, syncLock)))
180 nsk_jvmti_setFailStatus();
181
182 }
183
184 void JNICALL
cbException(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jobject exception,jmethodID catch_method,jlocation catch_location)185 cbException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
186 jmethodID method, jlocation location, jobject exception,
187 jmethodID catch_method, jlocation catch_location) {
188 changeCount(JVMTI_EVENT_EXCEPTION, &eventCount[0]);
189 }
190
191 void JNICALL
cbExceptionCatch(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jobject exception)192 cbExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
193 jmethodID method, jlocation location, jobject exception) {
194 changeCount(JVMTI_EVENT_EXCEPTION_CATCH, &eventCount[0]);
195 }
196
197 void JNICALL
cbSingleStep(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location)198 cbSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
199 jmethodID method, jlocation location) {
200 changeCount(JVMTI_EVENT_SINGLE_STEP, &eventCount[0]);
201 }
202
203 void JNICALL
cbFramePop(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jboolean was_popped_by_exception)204 cbFramePop(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
205 jmethodID method, jboolean was_popped_by_exception) {
206 changeCount(JVMTI_EVENT_FRAME_POP, &eventCount[0]);
207 }
208
209 void JNICALL
cbBreakpoint(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location)210 cbBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
211 jmethodID method, jlocation location) {
212 changeCount(JVMTI_EVENT_BREAKPOINT, &eventCount[0]);
213 }
214
215 void JNICALL
cbFieldAccess(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field)216 cbFieldAccess(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
217 jmethodID method, jlocation location, jclass field_klass,
218 jobject object, jfieldID field) {
219 changeCount(JVMTI_EVENT_FIELD_ACCESS, &eventCount[0]);
220 }
221
222 void JNICALL
cbFieldModification(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field,char signature_type,jvalue new_value)223 cbFieldModification(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
224 jmethodID method, jlocation location, jclass field_klass,
225 jobject object, jfieldID field, char signature_type,
226 jvalue new_value) {
227 changeCount(JVMTI_EVENT_FIELD_MODIFICATION, &eventCount[0]);
228 }
229
230 void JNICALL
cbMethodEntry(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method)231 cbMethodEntry(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
232 jmethodID method) {
233 changeCount(JVMTI_EVENT_METHOD_ENTRY, &eventCount[0]);
234 }
235
236 void JNICALL
cbMethodExit(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jboolean was_popped_by_exception,jvalue return_value)237 cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
238 jmethodID method, jboolean was_popped_by_exception,
239 jvalue return_value) {
240 changeCount(JVMTI_EVENT_METHOD_EXIT, &eventCount[0]);
241 }
242
243 void JNICALL
cbNativeMethodBind(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,void * address,void ** new_address_ptr)244 cbNativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env,jthread thread,
245 jmethodID method, void* address, void** new_address_ptr) {
246 changeCount(JVMTI_EVENT_NATIVE_METHOD_BIND, &eventCount[0]);
247 }
248
249 void JNICALL
cbMonitorWait(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jlong tout)250 cbMonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
251 jobject object, jlong tout) {
252
253 changeCount(JVMTI_EVENT_MONITOR_WAIT, &eventCount[0]);
254 }
255
256 void JNICALL
cbMonitorWaited(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jboolean timed_out)257 cbMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
258 jobject object, jboolean timed_out) {
259
260 changeCount(JVMTI_EVENT_MONITOR_WAITED, &eventCount[0]);
261 }
262
263 JNIEXPORT void JNICALL
cbMonitorContendedEnter(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread,jobject object)264 cbMonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread,
265 jobject object) {
266
267 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, &eventCount[0]);
268 }
269
270 void JNICALL
cbMonitorContendedEntered(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object)271 cbMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
272 jobject object) {
273
274 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, &eventCount[0]);
275 }
276
277 void JNICALL
cbCompiledMethodLoad(jvmtiEnv * jvmti_env,jmethodID method,jint code_size,const void * code_addr,jint map_length,const jvmtiAddrLocationMap * map,const void * compile_info)278 cbCompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size,
279 const void* code_addr, jint map_length,
280 const jvmtiAddrLocationMap* map, const void* compile_info) {
281 changeCount(JVMTI_EVENT_COMPILED_METHOD_LOAD, &eventCount[0]);
282 }
283
284 void JNICALL
cbCompiledMethodUnload(jvmtiEnv * jvmti_env,jmethodID method,const void * code_addr)285 cbCompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method,
286 const void* code_addr) {
287 changeCount(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, &eventCount[0]);
288 }
289
290 void JNICALL
cbGarbageCollectionStart(jvmtiEnv * jvmti_env)291 cbGarbageCollectionStart(jvmtiEnv *jvmti_env) {
292 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_START, &eventCount[0]);
293 }
294
295 void JNICALL
cbGarbageCollectionFinish(jvmtiEnv * jvmti_env)296 cbGarbageCollectionFinish(jvmtiEnv *jvmti_env) {
297 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, &eventCount[0]);
298 }
299
300 void JNICALL
cbObjectFree(jvmtiEnv * jvmti_env,jlong tag)301 cbObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
302
303 changeCount(JVMTI_EVENT_OBJECT_FREE, &eventCount[0]);
304 if (tag < 1 || tag > OBJECT_NUMBER) {
305 NSK_COMPLAIN1("Unexpected tag value %lld\n", tag);
306 nsk_jvmti_setFailStatus();
307 }
308 }
309
310 void JNICALL
cbNewObjectFree(jvmtiEnv * jvmti_env,jlong tag)311 cbNewObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
312
313 changeCount(JVMTI_EVENT_OBJECT_FREE, &newEventCount[0]);
314 if (tag < 1 || tag > OBJECT_NUMBER) {
315 NSK_COMPLAIN1("Unexpected tag value %lld\n", tag);
316 nsk_jvmti_setFailStatus();
317 }
318 }
319
320 void JNICALL
cbVMObjectAlloc(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jclass object_klass,jlong size)321 cbVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
322 jobject object, jclass object_klass, jlong size) {
323
324 changeCount(JVMTI_EVENT_VM_OBJECT_ALLOC, &eventCount[0]);
325 }
326
327 /* ============================================================================= */
328
enableEvent(jvmtiEvent event)329 static int enableEvent(jvmtiEvent event) {
330
331 if (nsk_jvmti_isOptionalEvent(event)
332 && (event != JVMTI_EVENT_OBJECT_FREE)) {
333 if (!NSK_JVMTI_VERIFY_CODE(JVMTI_ERROR_MUST_POSSESS_CAPABILITY,
334 NSK_CPP_STUB4(SetEventNotificationMode, jvmti,
335 JVMTI_ENABLE, event, NULL))) {
336 NSK_COMPLAIN1("Unexpected error enabling %s\n",
337 TranslateEvent(event));
338 return NSK_FALSE;
339 }
340 } else {
341 if (!NSK_JVMTI_VERIFY(
342 NSK_CPP_STUB4(SetEventNotificationMode, jvmti,
343 JVMTI_ENABLE, event, NULL))) {
344 NSK_COMPLAIN1("Unexpected error enabling %s\n",
345 TranslateEvent(event));
346 return NSK_FALSE;
347 }
348 }
349
350 return NSK_TRUE;
351 }
352
353 /**
354 * Enable or disable tested events.
355 */
enableEventList()356 static int enableEventList() {
357
358 int i, result;
359
360 result = enableEvent(JVMTI_EVENT_VM_INIT);
361
362 result = result && enableEvent(JVMTI_EVENT_VM_DEATH);
363
364 /* enabling optional events */
365 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
366 jvmtiEvent event = (jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL);
367
368 if (nsk_jvmti_isOptionalEvent(event))
369 result = result && enableEvent(event);
370 }
371
372 if (result == NSK_FALSE) {
373 nsk_jvmti_setFailStatus();
374 return NSK_FALSE;
375 }
376
377 return NSK_TRUE;
378 }
379
380 /* ============================================================================= */
381
382 static int
setCallBacks(int step)383 setCallBacks(int step) {
384
385 int i;
386
387 jvmtiEventCallbacks eventCallbacks;
388 memset(&eventCallbacks, 0, sizeof(eventCallbacks));
389
390 switch (step) {
391 case 1:
392 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
393 eventCount[i] = 0;
394 }
395
396 eventCallbacks.VMInit = cbVMInit;
397 eventCallbacks.Exception = cbException;
398 eventCallbacks.ExceptionCatch = cbExceptionCatch;
399 eventCallbacks.SingleStep = cbSingleStep;
400 eventCallbacks.FramePop = cbFramePop;
401 eventCallbacks.Breakpoint = cbBreakpoint;
402 eventCallbacks.FieldAccess = cbFieldAccess;
403 eventCallbacks.FieldModification = cbFieldModification;
404 eventCallbacks.MethodEntry = cbMethodEntry;
405 eventCallbacks.MethodExit = cbMethodExit;
406 eventCallbacks.NativeMethodBind = cbNativeMethodBind;
407 eventCallbacks.CompiledMethodLoad = cbCompiledMethodLoad;
408 eventCallbacks.CompiledMethodUnload = cbCompiledMethodUnload;
409 eventCallbacks.MonitorWait = cbMonitorWait;
410 eventCallbacks.MonitorWaited = cbMonitorWaited;
411 eventCallbacks.MonitorContendedEnter = cbMonitorContendedEnter;
412 eventCallbacks.MonitorContendedEntered = cbMonitorContendedEntered;
413 eventCallbacks.GarbageCollectionStart = cbGarbageCollectionStart;
414 eventCallbacks.GarbageCollectionFinish = cbGarbageCollectionFinish;
415 eventCallbacks.ObjectFree = cbObjectFree;
416 eventCallbacks.VMObjectAlloc = cbVMObjectAlloc;
417 break;
418
419 case 2:
420 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
421 newEventCount[i] = 0;
422 }
423
424 eventCallbacks.ObjectFree = cbNewObjectFree;
425 break;
426
427 case 3:
428 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
429 newEventCount[i] = 0;
430 }
431
432 eventCallbacks.VMDeath = cbVMDeath;
433 break;
434
435 }
436 if (!NSK_JVMTI_VERIFY(
437 NSK_CPP_STUB3(SetEventCallbacks, jvmti,
438 &eventCallbacks,
439 sizeof(eventCallbacks))))
440 return NSK_FALSE;
441
442 return NSK_TRUE;
443 }
444
445 /* ============================================================================= */
446
447 /** Agent algorithm. */
448 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * agentJNI,void * arg)449 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
450
451 int i;
452
453 for (i = 1; i <= STEP_NUMBER; i++) {
454
455 if (!nsk_jvmti_waitForSync(timeout))
456 return;
457
458 NSK_DISPLAY0("Check received events\n");
459
460 if (i < STEP_NUMBER) {
461 showEventStatistics(i);
462 if (!checkEvents(i))
463 nsk_jvmti_setFailStatus();
464
465 if (!setCallBacks(i + 1)) {
466 return;
467 }
468 }
469
470 if (!nsk_jvmti_resumeSync())
471 return;
472 }
473
474 }
475
476 /* ============================================================================= */
477
478 /** Agent library initialization. */
479 #ifdef STATIC_BUILD
Agent_OnLoad_em02t006(JavaVM * jvm,char * options,void * reserved)480 JNIEXPORT jint JNICALL Agent_OnLoad_em02t006(JavaVM *jvm, char *options, void *reserved) {
481 return Agent_Initialize(jvm, options, reserved);
482 }
Agent_OnAttach_em02t006(JavaVM * jvm,char * options,void * reserved)483 JNIEXPORT jint JNICALL Agent_OnAttach_em02t006(JavaVM *jvm, char *options, void *reserved) {
484 return Agent_Initialize(jvm, options, reserved);
485 }
JNI_OnLoad_em02t006(JavaVM * jvm,char * options,void * reserved)486 JNIEXPORT jint JNI_OnLoad_em02t006(JavaVM *jvm, char *options, void *reserved) {
487 return JNI_VERSION_1_8;
488 }
489 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)490 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
491
492 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
493 return JNI_ERR;
494
495 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
496
497 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
498 return JNI_ERR;
499
500 if (!NSK_JVMTI_VERIFY(
501 NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_syncLock", &syncLock))) {
502 nsk_jvmti_setFailStatus();
503 return JNI_ERR;
504 }
505
506 {
507 jvmtiCapabilities caps;
508 memset(&caps, 0, sizeof(caps));
509
510 caps.can_tag_objects = 1;
511 caps.can_generate_object_free_events = 1;
512 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps)))
513 return JNI_ERR;
514 }
515
516 if (!setCallBacks(1)) {
517 return JNI_ERR;
518 }
519
520 if (!enableEventList()) {
521 return JNI_ERR;
522 }
523
524 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
525 return JNI_ERR;
526
527 return JNI_OK;
528 }
529
530 /* ============================================================================= */
531
532
533 #ifdef __cplusplus
534 }
535 #endif
536