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