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