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 JNIEnv* jni = NULL; 37 static jvmtiEnv *jvmti = NULL; 38 static jlong timeout = 0; 39 static jrawMonitorID syncLock = NULL; 40 41 /* constant names */ 42 #define DEBUGEE_CLASS_NAME "nsk/jvmti/scenarios/events/EM02/em02t001" 43 #define START_FIELD_NAME "startingMonitor" 44 #define END_FIELD_NAME "endingMonitor" 45 #define MAIN_THREAD_NAME "main" 46 #define THREAD_FIELD_NAME "debuggeeThread" 47 #define OBJECT_FIELD_SIG "Ljava/lang/Object;" 48 #define THREAD_FIELD_SIG "Ljava/lang/Thread;" 49 50 static jthread mainThread = NULL; 51 static jthread debuggeeThread = NULL; 52 static jobject startObject = NULL; 53 static jobject endObject = NULL; 54 55 #define STEP_AMOUNT 3 56 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1) 57 static int eventCount[JVMTI_EVENT_COUNT]; 58 static int newEventCount[JVMTI_EVENT_COUNT]; 59 60 /* ============================================================================= */ 61 62 static jthread 63 findThread(const char *threadName) { 64 jvmtiThreadInfo info; 65 jthread *threads = NULL; 66 jint threads_count = 0; 67 jthread returnValue = NULL; 68 int i; 69 70 /* get all live threads */ 71 if (!NSK_JVMTI_VERIFY(jvmti->GetAllThreads(&threads_count, &threads))) 72 return NULL; 73 74 if (!NSK_VERIFY(threads != NULL)) 75 return NULL; 76 77 /* find tested thread */ 78 for (i = 0; i < threads_count; i++) { 79 if (!NSK_VERIFY(threads[i] != NULL)) 80 break; 81 82 /* get thread information */ 83 if (!NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(threads[i], &info))) 84 break; 85 86 /* find by name */ 87 if (info.name != NULL && (strcmp(info.name, threadName) == 0)) { 88 returnValue = threads[i]; 89 } 90 } 91 92 /* deallocate threads list */ 93 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)threads))) 94 return NULL; 95 96 return returnValue; 97 } 98 99 /* ============================================================================= */ 100 101 static jobject 102 getStaticObjField(const char* className, const char* objFieldName, 103 const char* signature) { 104 105 jfieldID fieldID; 106 jclass klass = NULL; 107 108 klass = jni->FindClass(className); 109 if (!NSK_JNI_VERIFY(jni, klass != NULL)) 110 return NULL; 111 112 fieldID = jni->GetStaticFieldID(klass, objFieldName, signature); 113 if (!NSK_JNI_VERIFY(jni, fieldID != NULL)) 114 return NULL; 115 116 return jni->GetStaticObjectField(klass, fieldID); 117 } 118 119 /* ============================================================================= */ 120 121 static int prepare() { 122 123 mainThread = findThread(MAIN_THREAD_NAME); 124 if (!NSK_VERIFY(mainThread != NULL)) { 125 NSK_COMPLAIN1("<%s> thread not found\n", MAIN_THREAD_NAME); 126 return NSK_FALSE; 127 } 128 129 /* make thread accessable for a long time */ 130 mainThread = jni->NewGlobalRef(mainThread); 131 if (!NSK_JNI_VERIFY(jni, mainThread != NULL)) 132 return NSK_FALSE; 133 134 startObject = getStaticObjField(DEBUGEE_CLASS_NAME, START_FIELD_NAME, OBJECT_FIELD_SIG); 135 if (!NSK_VERIFY(startObject != NULL)) 136 return NSK_FALSE; 137 138 /*make object accessable for a long time*/ 139 startObject = jni->NewGlobalRef(startObject); 140 if (!NSK_JNI_VERIFY(jni, startObject != NULL)) 141 return NSK_FALSE; 142 143 144 endObject = getStaticObjField(DEBUGEE_CLASS_NAME, END_FIELD_NAME, OBJECT_FIELD_SIG); 145 if (!NSK_VERIFY(endObject != NULL)) 146 return NSK_FALSE; 147 148 /*make object accessable for a long time*/ 149 endObject = jni->NewGlobalRef(endObject); 150 if (!NSK_JNI_VERIFY(jni, endObject != NULL)) 151 return NSK_FALSE; 152 153 154 debuggeeThread = (jthread) getStaticObjField(DEBUGEE_CLASS_NAME, 155 THREAD_FIELD_NAME, 156 THREAD_FIELD_SIG); 157 if (!NSK_VERIFY(debuggeeThread != NULL)) 158 return NSK_FALSE; 159 160 /* make thread accessable for a long time */ 161 debuggeeThread = jni->NewGlobalRef(debuggeeThread); 162 if (!NSK_JNI_VERIFY(jni, debuggeeThread != NULL)) 163 return NSK_FALSE; 164 165 return NSK_TRUE; 166 } 167 168 /* ============================================================================= */ 169 170 static int 171 clean() { 172 173 /* disable MonitorContendedEnter event */ 174 if (!NSK_JVMTI_VERIFY( 175 jvmti->SetEventNotificationMode( 176 JVMTI_DISABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL))) 177 nsk_jvmti_setFailStatus(); 178 179 /* dispose global references */ 180 jni->DeleteGlobalRef(startObject); 181 jni->DeleteGlobalRef(endObject); 182 jni->DeleteGlobalRef(debuggeeThread); 183 jni->DeleteGlobalRef(mainThread); 184 185 startObject = NULL; 186 endObject = NULL; 187 debuggeeThread = NULL; 188 mainThread = NULL; 189 190 return NSK_TRUE; 191 } 192 193 /* ========================================================================== */ 194 195 static void 196 showEventStatistics(int step /*int *currentCounts*/) { 197 int i; 198 const char* str; 199 int *currentCounts = (step == 1) ? &eventCount[0] : &newEventCount[0]; 200 201 NSK_DISPLAY0("\n"); 202 NSK_DISPLAY1("Event statistics for %d step:\n", step); 203 NSK_DISPLAY0("-----------------------------\n"); 204 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 205 if (currentCounts[i] > 0) { 206 str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL)); 207 NSK_DISPLAY2("%-40s %7d\n", str, currentCounts[i]); 208 } 209 } 210 } 211 212 /* ========================================================================== */ 213 214 /* get thread information */ 215 static void 216 showThreadInfo(jthread thread) { 217 jvmtiThreadInfo info; 218 if (!NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(thread, &info))) 219 return; 220 221 NSK_DISPLAY2("\tthread (%s): %p\n", info.name, thread); 222 } 223 224 /* ============================================================================= */ 225 226 static void 227 changeCount(jvmtiEvent event, int *currentCounts) { 228 229 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(syncLock))) 230 nsk_jvmti_setFailStatus(); 231 232 currentCounts[event - JVMTI_MIN_EVENT_TYPE_VAL]++; 233 234 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(syncLock))) 235 nsk_jvmti_setFailStatus(); 236 237 } 238 239 /* ============================================================================= */ 240 241 int checkEvents(int step) { 242 int i; 243 jvmtiEvent curr; 244 int result = NSK_TRUE; 245 int *currentCounts; 246 int isExpected = 0; 247 248 switch (step) { 249 case 1: 250 currentCounts = &eventCount[0]; 251 break; 252 253 case 2: 254 case 3: 255 currentCounts = &newEventCount[0]; 256 break; 257 258 default: 259 NSK_COMPLAIN1("Unexpected step no: %d\n", step); 260 return NSK_FALSE; 261 } 262 263 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 264 265 curr = (jvmtiEvent)(i + JVMTI_MIN_EVENT_TYPE_VAL); 266 267 switch (step) { 268 case 1: 269 isExpected = ((curr == JVMTI_EVENT_MONITOR_CONTENDED_ENTER) 270 || (curr == JVMTI_EVENT_MONITOR_CONTENDED_ENTERED) 271 || (curr == JVMTI_EVENT_MONITOR_WAIT) 272 || (curr == JVMTI_EVENT_MONITOR_WAITED) 273 || (curr == JVMTI_EVENT_VM_INIT)); 274 break; 275 276 case 2: 277 isExpected = ((curr == JVMTI_EVENT_MONITOR_CONTENDED_ENTER) 278 || (curr == JVMTI_EVENT_MONITOR_CONTENDED_ENTERED) 279 || (curr == JVMTI_EVENT_MONITOR_WAIT) 280 || (curr == JVMTI_EVENT_MONITOR_WAITED)); 281 break; 282 283 case 3: 284 isExpected = (curr == JVMTI_EVENT_VM_DEATH); 285 break; 286 } 287 288 if (isExpected) { 289 if (currentCounts[i] != 1) { 290 nsk_jvmti_setFailStatus(); 291 NSK_COMPLAIN2("Unexpected events number %7d for %s\n\texpected value is 1\n", 292 currentCounts[i], 293 TranslateEvent(curr)); 294 result = NSK_FALSE; 295 } 296 } else { 297 if (currentCounts[i] > 0) { 298 NSK_COMPLAIN2("Unexpected event %s was sent %d times\n", 299 TranslateEvent(curr), 300 currentCounts[i]); 301 result = NSK_FALSE; 302 } 303 } 304 } 305 306 return result; 307 } 308 309 /* ============================================================================= */ 310 311 /* callbacks */ 312 JNIEXPORT void JNICALL 313 cbVMInit(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread) { 314 changeCount(JVMTI_EVENT_VM_INIT, &eventCount[0]); 315 } 316 317 JNIEXPORT void JNICALL 318 cbVMDeath(jvmtiEnv* jvmti, JNIEnv* jni_env) { 319 changeCount(JVMTI_EVENT_VM_DEATH, &newEventCount[0]); 320 showEventStatistics(STEP_AMOUNT); 321 if (!checkEvents(STEP_AMOUNT)) { 322 nsk_jvmti_setFailStatus(); 323 } 324 325 if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) 326 nsk_jvmti_setFailStatus(); 327 328 } 329 330 void JNICALL 331 cbException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 332 jmethodID method, jlocation location, jobject exception, 333 jmethodID catch_method, jlocation catch_location) { 334 changeCount(JVMTI_EVENT_EXCEPTION, &eventCount[0]); 335 } 336 337 void JNICALL 338 cbExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 339 jmethodID method, jlocation location, jobject exception) { 340 changeCount(JVMTI_EVENT_EXCEPTION_CATCH, &eventCount[0]); 341 } 342 343 void JNICALL 344 cbSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 345 jmethodID method, jlocation location) { 346 changeCount(JVMTI_EVENT_SINGLE_STEP, &eventCount[0]); 347 } 348 349 void JNICALL 350 cbFramePop(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 351 jmethodID method, jboolean was_popped_by_exception) { 352 changeCount(JVMTI_EVENT_FRAME_POP, &eventCount[0]); 353 } 354 355 void JNICALL 356 cbBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 357 jmethodID method, jlocation location) { 358 changeCount(JVMTI_EVENT_BREAKPOINT, &eventCount[0]); 359 } 360 361 void JNICALL 362 cbFieldAccess(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 363 jmethodID method, jlocation location, jclass field_klass, 364 jobject object, jfieldID field) { 365 changeCount(JVMTI_EVENT_FIELD_ACCESS, &eventCount[0]); 366 } 367 368 void JNICALL 369 cbFieldModification(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 370 jmethodID method, jlocation location, jclass field_klass, 371 jobject object, jfieldID field, char signature_type, 372 jvalue new_value) { 373 changeCount(JVMTI_EVENT_FIELD_MODIFICATION, &eventCount[0]); 374 } 375 376 void JNICALL 377 cbMethodEntry(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 378 jmethodID method) { 379 changeCount(JVMTI_EVENT_METHOD_ENTRY, &eventCount[0]); 380 } 381 382 void JNICALL 383 cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 384 jmethodID method, jboolean was_popped_by_exception, 385 jvalue return_value) { 386 changeCount(JVMTI_EVENT_METHOD_EXIT, &eventCount[0]); 387 } 388 389 void JNICALL 390 cbNativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env,jthread thread, 391 jmethodID method, void* address, void** new_address_ptr) { 392 changeCount(JVMTI_EVENT_NATIVE_METHOD_BIND, &eventCount[0]); 393 } 394 395 void JNICALL 396 cbCompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size, 397 const void* code_addr, jint map_length, 398 const jvmtiAddrLocationMap* map, const void* compile_info) { 399 changeCount(JVMTI_EVENT_COMPILED_METHOD_LOAD, &eventCount[0]); 400 } 401 402 void JNICALL 403 cbCompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method, 404 const void* code_addr) { 405 changeCount(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, &eventCount[0]); 406 } 407 408 void 409 handlerMC1(jvmtiEvent event, jvmtiEnv* jvmti, JNIEnv* jni_env, 410 jthread thread, jobject object, 411 jthread expectedThread, jobject expectedObject) { 412 413 if (expectedThread == NULL || expectedObject == NULL) 414 return; 415 416 /* check if event is for tested thread and for tested object */ 417 if (jni_env->IsSameObject(expectedThread, thread) && 418 jni_env->IsSameObject(expectedObject, object)) { 419 420 NSK_DISPLAY1("--->%-40s is received\n", TranslateEvent(event)); 421 422 showThreadInfo(thread); 423 if (jni_env->IsSameObject(expectedObject, endObject)) 424 NSK_DISPLAY0("\tobject: 'endingMonitor'\n"); 425 else 426 NSK_DISPLAY0("\tobject: 'startingMonitor'\n"); 427 428 changeCount(event, &eventCount[0]); 429 } 430 } 431 432 void JNICALL 433 cbMonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 434 jobject object, jlong tout) { 435 436 handlerMC1(JVMTI_EVENT_MONITOR_WAIT, 437 jvmti, jni_env, 438 thread, object, 439 mainThread, startObject); 440 } 441 442 void JNICALL 443 cbMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 444 jobject object, jboolean timed_out) { 445 446 handlerMC1(JVMTI_EVENT_MONITOR_WAITED, 447 jvmti, jni_env, 448 thread, object, 449 mainThread, startObject); 450 } 451 452 JNIEXPORT void JNICALL 453 cbMonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread, 454 jobject object) { 455 456 handlerMC1(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 457 jvmti, jni_env, 458 thread, object, 459 debuggeeThread, endObject); 460 } 461 462 void JNICALL 463 cbMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 464 jobject object) { 465 466 handlerMC1(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 467 jvmti_env, jni_env, 468 thread, object, 469 debuggeeThread, endObject); 470 } 471 472 void JNICALL 473 cbGarbageCollectionStart(jvmtiEnv *jvmti_env) { 474 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_START, &eventCount[0]); 475 } 476 477 void JNICALL 478 cbGarbageCollectionFinish(jvmtiEnv *jvmti_env) { 479 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, &eventCount[0]); 480 } 481 482 void JNICALL 483 cbObjectFree(jvmtiEnv *jvmti_env, jlong tag) { 484 changeCount(JVMTI_EVENT_OBJECT_FREE, &eventCount[0]); 485 } 486 487 void JNICALL 488 cbVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 489 jobject object, jclass object_klass, jlong size) { 490 491 changeCount(JVMTI_EVENT_VM_OBJECT_ALLOC, &eventCount[0]); 492 } 493 494 void 495 handlerMC2(jvmtiEvent event, jvmtiEnv* jvmti, JNIEnv* jni_env, 496 jthread thread, jobject object, 497 jthread expectedThread, jobject expectedObject) { 498 499 if (expectedThread == NULL || expectedObject == NULL) 500 return; 501 502 /* check if event is for tested thread and for tested object */ 503 if (jni_env->IsSameObject(expectedThread, thread) && 504 jni_env->IsSameObject(expectedObject, object)) { 505 506 NSK_DISPLAY1("--->%-40s is received (new callbacks)\n", TranslateEvent(event)); 507 508 showThreadInfo(thread); 509 if (jni_env->IsSameObject(expectedObject, endObject)) 510 NSK_DISPLAY0("\tobject: 'endingMonitor'\n"); 511 else 512 NSK_DISPLAY0("\tobject: 'startingMonitor'\n"); 513 514 515 changeCount(event, &newEventCount[0]); 516 } 517 } 518 519 void JNICALL 520 cbNewMonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 521 jobject object, jlong tout) { 522 523 handlerMC2(JVMTI_EVENT_MONITOR_WAIT, 524 jvmti_env, jni_env, 525 thread, object, 526 mainThread, startObject); 527 } 528 529 void JNICALL 530 cbNewMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 531 jobject object, jboolean timed_out) { 532 533 handlerMC2(JVMTI_EVENT_MONITOR_WAITED, 534 jvmti, jni_env, 535 thread, object, 536 mainThread, startObject); 537 } 538 539 void JNICALL 540 cbNewMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 541 jobject object) { 542 543 handlerMC2(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 544 jvmti, jni_env, 545 thread, object, 546 debuggeeThread, endObject); 547 } 548 549 JNIEXPORT void JNICALL 550 cbNewMonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread, 551 jobject object) { 552 553 handlerMC2(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 554 jvmti, jni_env, 555 thread, object, 556 debuggeeThread, endObject); 557 } 558 559 /* ============================================================================= */ 560 561 static int enableEvent(jvmtiEvent event) { 562 563 if (nsk_jvmti_isOptionalEvent(event) 564 && (event != JVMTI_EVENT_MONITOR_CONTENDED_ENTER) 565 && (event != JVMTI_EVENT_MONITOR_CONTENDED_ENTERED) 566 && (event != JVMTI_EVENT_MONITOR_WAIT) 567 && (event != JVMTI_EVENT_MONITOR_WAITED)) { 568 if (!NSK_JVMTI_VERIFY_CODE(JVMTI_ERROR_MUST_POSSESS_CAPABILITY, 569 jvmti->SetEventNotificationMode(JVMTI_ENABLE, event, NULL))) { 570 NSK_COMPLAIN1("Unexpected error enabling %s\n", 571 TranslateEvent(event)); 572 return NSK_FALSE; 573 } 574 } else { 575 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, event, NULL))) { 576 NSK_COMPLAIN1("Unexpected error enabling %s\n", 577 TranslateEvent(event)); 578 return NSK_FALSE; 579 } 580 } 581 582 return NSK_TRUE; 583 } 584 585 static int enableEventList() { 586 int i; 587 int result = NSK_TRUE; 588 589 NSK_DISPLAY0("Enable events\n"); 590 591 result = enableEvent(JVMTI_EVENT_VM_INIT); 592 593 result = result && enableEvent(JVMTI_EVENT_VM_DEATH); 594 595 /* enabling optional events */ 596 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 597 jvmtiEvent event = (jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL); 598 599 if (nsk_jvmti_isOptionalEvent(event)) 600 result = result && enableEvent(event); 601 } 602 603 if (result == NSK_FALSE) { 604 nsk_jvmti_setFailStatus(); 605 return NSK_FALSE; 606 } 607 608 return NSK_TRUE; 609 } 610 611 /* ============================================================================= */ 612 613 static int 614 setCallBacks(int step) { 615 616 int i; 617 618 jvmtiEventCallbacks eventCallbacks; 619 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 620 621 NSK_DISPLAY0("\n"); 622 NSK_DISPLAY1("===============step %d===============\n", step); 623 NSK_DISPLAY0("\n"); 624 switch (step) { 625 case 1: 626 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 627 eventCount[i] = 0; 628 } 629 630 eventCallbacks.VMInit = cbVMInit; 631 eventCallbacks.Exception = cbException; 632 eventCallbacks.ExceptionCatch = cbExceptionCatch; 633 eventCallbacks.SingleStep = cbSingleStep; 634 eventCallbacks.FramePop = cbFramePop; 635 eventCallbacks.Breakpoint = cbBreakpoint; 636 eventCallbacks.FieldAccess = cbFieldAccess; 637 eventCallbacks.FieldModification = cbFieldModification; 638 eventCallbacks.MethodEntry = cbMethodEntry; 639 eventCallbacks.MethodExit = cbMethodExit; 640 eventCallbacks.NativeMethodBind = cbNativeMethodBind; 641 eventCallbacks.CompiledMethodLoad = cbCompiledMethodLoad; 642 eventCallbacks.CompiledMethodUnload = cbCompiledMethodUnload; 643 eventCallbacks.MonitorWait = cbMonitorWait; 644 eventCallbacks.MonitorWaited = cbMonitorWaited; 645 eventCallbacks.MonitorContendedEnter = cbMonitorContendedEnter; 646 eventCallbacks.MonitorContendedEntered = cbMonitorContendedEntered; 647 eventCallbacks.GarbageCollectionStart = cbGarbageCollectionStart; 648 eventCallbacks.GarbageCollectionFinish = cbGarbageCollectionFinish; 649 eventCallbacks.ObjectFree = cbObjectFree; 650 eventCallbacks.VMObjectAlloc = cbVMObjectAlloc; 651 break; 652 653 case 2: 654 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 655 newEventCount[i] = 0; 656 } 657 658 eventCallbacks.MonitorWait = cbNewMonitorWait; 659 eventCallbacks.MonitorWaited = cbNewMonitorWaited; 660 eventCallbacks.MonitorContendedEnter = cbNewMonitorContendedEnter; 661 eventCallbacks.MonitorContendedEntered = cbNewMonitorContendedEntered; 662 break; 663 664 case 3: 665 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 666 newEventCount[i] = 0; 667 } 668 669 eventCallbacks.VMDeath = cbVMDeath; 670 break; 671 672 } 673 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 674 return NSK_FALSE; 675 676 return NSK_TRUE; 677 } 678 679 /* ============================================================================= */ 680 681 /** Agent algorithm. */ 682 static void JNICALL 683 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 684 685 int i; 686 jni = agentJNI; 687 688 for (i = 1; i <= STEP_AMOUNT; i++) { 689 if (i > 1) { 690 NSK_DISPLAY0("Check received events\n"); 691 692 showEventStatistics(i-1); 693 if (!checkEvents(i-1)) { 694 nsk_jvmti_setFailStatus(); 695 } 696 697 if (!setCallBacks(i)) { 698 return; 699 } 700 701 if (!nsk_jvmti_resumeSync()) 702 return; 703 } 704 705 NSK_DISPLAY0("Wait for debuggee to become ready\n"); 706 if (!nsk_jvmti_waitForSync(timeout)) 707 return; 708 709 prepare(); 710 711 if (!nsk_jvmti_resumeSync()) 712 return; 713 714 715 NSK_DISPLAY0("Waiting events\n"); /* thread started */ 716 if (!nsk_jvmti_waitForSync(timeout)) 717 return; 718 719 if (!nsk_jvmti_resumeSync()) 720 return; 721 722 if (!nsk_jvmti_waitForSync(timeout)) 723 return; 724 725 } 726 727 if (!clean()) { 728 nsk_jvmti_setFailStatus(); 729 return; 730 } 731 732 NSK_DISPLAY0("Let debuggee to finish\n"); 733 if (!nsk_jvmti_resumeSync()) 734 return; 735 736 } 737 738 /* ============================================================================= */ 739 740 /** Agent library initialization. */ 741 #ifdef STATIC_BUILD 742 JNIEXPORT jint JNICALL Agent_OnLoad_em02t001(JavaVM *jvm, char *options, void *reserved) { 743 return Agent_Initialize(jvm, options, reserved); 744 } 745 JNIEXPORT jint JNICALL Agent_OnAttach_em02t001(JavaVM *jvm, char *options, void *reserved) { 746 return Agent_Initialize(jvm, options, reserved); 747 } 748 JNIEXPORT jint JNI_OnLoad_em02t001(JavaVM *jvm, char *options, void *reserved) { 749 return JNI_VERSION_1_8; 750 } 751 #endif 752 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 753 754 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 755 return JNI_ERR; 756 757 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 758 759 jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved); 760 if (!NSK_VERIFY(jvmti != NULL)) 761 return JNI_ERR; 762 763 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_syncLock", &syncLock))) { 764 nsk_jvmti_setFailStatus(); 765 return JNI_ERR; 766 } 767 768 { 769 jvmtiCapabilities caps; 770 memset(&caps, 0, sizeof(caps)); 771 772 caps.can_generate_monitor_events = 1; 773 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 774 return JNI_ERR; 775 } 776 777 if (!setCallBacks(1)) { 778 return JNI_ERR; 779 } 780 781 nsk_jvmti_showPossessedCapabilities(jvmti); 782 783 if (!enableEventList()) { 784 return JNI_ERR; 785 } 786 787 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 788 return JNI_ERR; 789 790 return JNI_OK; 791 } 792 793 /* ============================================================================= */ 794 795 796 }