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