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 30 extern "C" { 31 32 /* ============================================================================= */ 33 34 /* scaffold objects */ 35 static JNIEnv* jni = NULL; 36 static jvmtiEnv *jvmti = NULL; 37 static jlong timeout = 0; 38 39 /* constant names */ 40 #define EXPECTED_CLASS_NAME "nsk/jvmti/scenarios/hotswap/HS201/hs201t001a" 41 #define EXPECTED_CLASS_SIGN "Lnsk/jvmti/scenarios/hotswap/HS201/hs201t001a;" 42 #define METHOD_NAME "doInit" 43 #define METHOD_SIG "()V" 44 #define LOCAL_VARIABLE_NAME "localVariable" 45 #define PATH_TO_NEW_BYTECODE "pathToNewByteCode" 46 47 static jint testStep; 48 static int redefineNumber; 49 static jint newClassSize; 50 static unsigned char* newClassBytes; 51 static jthread testedThread; 52 static jclass testClass; 53 char chbuffer[255]; 54 55 const char* getThreadName(JNIEnv* jni_env, jthread thread); 56 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object); 57 int readNewBytecode(jvmtiEnv* jvmti, int testcase); 58 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread, jmethodID method); 59 60 /* ============================================================================= */ 61 62 void setCurrentStep(JNIEnv* jni_env, int value) { 63 64 jfieldID fld; 65 66 if (!NSK_JNI_VERIFY(jni_env, (fld = 67 jni_env->GetStaticFieldID(testClass, "currentStep", "I")) != NULL)) { 68 jni_env->FatalError("TEST FAILED: while getting currentStep fieldID\n"); 69 } 70 71 if (!NSK_JNI_VERIFY_VOID(jni_env, jni_env->SetStaticIntField(testClass, fld, value))) { 72 jni_env->FatalError("TEST FAILED: while setting value of currentStep fieldID\n"); 73 } 74 75 } 76 77 /* ============================================================================= */ 78 79 void enableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) { 80 81 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, event, thread))) { 82 NSK_COMPLAIN1("TEST FAILED: enabling %s\n", TranslateEvent(event)); 83 nsk_jvmti_setFailStatus(); 84 } 85 } 86 87 /* ============================================================================= */ 88 89 void disableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) { 90 91 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, event, thread))) { 92 NSK_COMPLAIN1("TEST FAILED: disabling %s\n", TranslateEvent(event)); 93 nsk_jvmti_setFailStatus(); 94 } 95 } 96 97 /* ============================================================================= */ 98 99 void redefineClass(jvmtiEnv *jvmti_env, jclass klass) { 100 101 jvmtiClassDefinition classDef; 102 103 char *className; 104 105 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, NULL))) { 106 nsk_jvmti_setFailStatus(); 107 return; 108 } 109 110 if (!NSK_VERIFY(readNewBytecode(jvmti_env, redefineNumber++))) { 111 NSK_COMPLAIN0("TEST FAILED: new bytecode could not be read\n"); 112 nsk_jvmti_setFailStatus(); 113 return; 114 } 115 116 classDef.klass = klass; 117 classDef.class_byte_count = newClassSize; 118 classDef.class_bytes = newClassBytes; 119 120 NSK_DISPLAY1("\tredefining class %s\n", className); 121 if (!NSK_JVMTI_VERIFY(jvmti_env->RedefineClasses(1, &classDef))) { 122 NSK_COMPLAIN1("TEST FAILED: while redefining class %s\n", className); 123 nsk_jvmti_setFailStatus(); 124 return; 125 } 126 127 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 128 nsk_jvmti_setFailStatus(); 129 } 130 131 } 132 133 /* ============================================================================= */ 134 135 /** Agent algorithm. */ 136 static void JNICALL 137 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 138 139 redefineNumber = 1; 140 jni = agentJNI; 141 142 NSK_DISPLAY0("Waiting for debuggee to become ready\n"); 143 if (!nsk_jvmti_waitForSync(timeout)) 144 return; 145 146 testStep = 1; 147 NSK_DISPLAY0("\n\n>>>> Debugge started, waiting for class loading \n"); 148 if (!nsk_jvmti_resumeSync()) 149 return; 150 151 NSK_DISPLAY0("Waiting for debuggee's threads to finish\n"); 152 if (!nsk_jvmti_waitForSync(timeout)) 153 return; 154 155 NSK_TRACE(jni->DeleteGlobalRef(testClass)); 156 NSK_TRACE(jni->DeleteGlobalRef(testedThread)); 157 158 NSK_DISPLAY0("Let debuggee to finish\n"); 159 if (!nsk_jvmti_resumeSync()) 160 return; 161 } 162 163 /* ============================================================================= */ 164 165 void setBreakPoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jclass klass) { 166 jmethodID mid; 167 168 if (!NSK_JNI_VERIFY(jni_env, (mid = jni_env->GetMethodID(klass, METHOD_NAME, METHOD_SIG)) != NULL)) 169 jni_env->FatalError("[agent] failed to get ID for the java method\n"); 170 171 if (!NSK_JVMTI_VERIFY(jvmti_env->SetBreakpoint(mid, 1))) 172 jni_env->FatalError("[agent] failed to set breakpoint\n"); 173 } 174 175 /* ============================================================================= */ 176 177 /** 178 * CLASS_LOAD callback. 179 * - 180 */ 181 JNIEXPORT void JNICALL 182 callbackClassLoad(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 183 jclass klass) { 184 185 char *className; 186 char *generic; 187 188 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, &generic))) { 189 nsk_jvmti_setFailStatus(); 190 return; 191 } 192 193 if (strcmp(className, EXPECTED_CLASS_SIGN) 194 == 0) { 195 196 NSK_DISPLAY1("\n\n>>>> Class loaded: %s", className); 197 NSK_DISPLAY0(", activating breakpoint\n"); 198 setBreakPoint(jvmti_env, jni_env, klass); 199 } 200 201 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 202 nsk_jvmti_setFailStatus(); 203 } 204 205 if (generic != NULL) 206 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) { 207 nsk_jvmti_setFailStatus(); 208 } 209 } 210 211 /* ============================================================================= */ 212 213 /** 214 * BREAKPOINT callback. 215 * - 216 */ 217 JNIEXPORT void JNICALL 218 callbackBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 219 jmethodID method, jlocation location) { 220 221 NSK_DISPLAY0("\n\n>>>>Breakpoint fired, enabling SINGLE_STEP\n"); 222 enableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread); 223 } 224 225 /* ============================================================================= */ 226 227 /** 228 * BREAKPOINT callback. 229 * - 230 */ 231 JNIEXPORT void JNICALL 232 callbackSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 233 jmethodID method, jlocation location) { 234 235 char *methodName; 236 237 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodName(method, &methodName, NULL, NULL))) { 238 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n"); 239 } 240 241 if (strcmp(methodName, METHOD_NAME) == 0) { 242 char *declaringClassName; 243 jclass declaringClass; 244 245 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &declaringClass))) { 246 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n"); 247 } 248 249 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(declaringClass, &declaringClassName, NULL))) { 250 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n"); 251 } 252 253 if (strcmp(declaringClassName, EXPECTED_CLASS_SIGN) == 0) { 254 int value; 255 jboolean is_obsolete; 256 257 /* getting local variable table*/ 258 value = getLocalVariableValue(jvmti_env, thread, method); 259 260 switch (testStep) { 261 case 1: 262 263 if (value == 1) { 264 redefineClass(jvmti_env, declaringClass); 265 testStep++; 266 } 267 break; 268 269 case 2: 270 271 NSK_DISPLAY1("\n\n>>>> Checking if redefined method is obsolete\n", testStep); 272 273 if (!NSK_JVMTI_VERIFY(jvmti->IsMethodObsolete(method, &is_obsolete))) { 274 NSK_COMPLAIN0("TEST FAILED: unable to check method to be obsolete\n"); 275 nsk_jvmti_setFailStatus(); 276 return; 277 } 278 279 if (!is_obsolete) { 280 NSK_COMPLAIN0("TEST FAILED: method must be obsolete\n"); 281 nsk_jvmti_setFailStatus(); 282 } 283 testStep++; 284 break; 285 286 case 3: 287 288 NSK_DISPLAY1("\n\n>>>> Popping the currently executing frame\n", testStep); 289 testStep++; 290 setCurrentStep(jni_env, testStep); 291 292 break; 293 294 case 5: 295 296 if (value > 10 && value < 1000) { 297 NSK_DISPLAY1("\n\n>>>> Disabling single step\n", testStep); 298 disableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread); 299 setCurrentStep(jni_env, testStep); 300 } 301 302 } /* case */ 303 304 } 305 306 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) declaringClassName))) { 307 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n"); 308 } 309 310 } 311 312 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methodName))) { 313 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n"); 314 } 315 316 } 317 318 /* ============================================================================= */ 319 320 /** 321 * EXCEPTION callback. 322 * - 323 */ 324 JNIEXPORT void JNICALL 325 callbackException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 326 jmethodID method, jlocation location, jobject exception, 327 jmethodID catch_method, jlocation catch_location) { 328 329 const char *className; 330 331 className = getClassName(jvmti_env, jni_env, exception); 332 333 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) { 334 jclass klass; 335 336 NSK_DISPLAY2("\n\n>>>> Exception %s in thread - %s\n", 337 className, getThreadName(jni_env, thread)); 338 339 testStep++; 340 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(exception)) != NULL)) { 341 nsk_jvmti_setFailStatus(); 342 return; 343 } 344 345 redefineClass(jvmti_env, klass); 346 } 347 } 348 349 /* ============================================================================= */ 350 351 /** 352 * EXCEPTION_CATCH callback. 353 * - 354 */ 355 JNIEXPORT void JNICALL 356 callbackExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 357 jmethodID method, jlocation location, 358 jobject exception) { 359 360 const char *className; 361 362 className = getClassName(jvmti_env, jni_env, exception); 363 364 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) { 365 jclass klass; 366 367 NSK_DISPLAY2("\n\n>>>> Caught exception %s in thread - %s\n", 368 className, getThreadName(jni_env, thread)); 369 370 testStep++; 371 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(exception)) != NULL)) { 372 nsk_jvmti_setFailStatus(); 373 return; 374 } 375 376 redefineClass(jvmti_env, klass); 377 } 378 } 379 380 /* ============================================================================= */ 381 382 int readNewBytecode(jvmtiEnv* jvmti, int testcase) { 383 384 char filename[256]; 385 FILE *bytecode; 386 const char *pathToByteCode = nsk_jvmti_findOptionValue(PATH_TO_NEW_BYTECODE); 387 jint read_bytes; 388 389 390 if (!pathToByteCode) { 391 NSK_COMPLAIN0("TEST FAILED: error opening file\n"); 392 return NSK_FALSE; 393 } 394 395 sprintf(filename,"%s/%s%02d/%s.class", 396 pathToByteCode, "newclass", testcase, EXPECTED_CLASS_NAME); 397 398 NSK_DISPLAY1("\treading new bytecode for the tested class\n\tfile name: %s\n", 399 filename); 400 401 bytecode = fopen(filename, "rb"); 402 if (bytecode == NULL) { 403 NSK_COMPLAIN0("TEST FAILED: error opening file\n"); 404 return NSK_FALSE; 405 } 406 407 fseek(bytecode, 0, SEEK_END); 408 newClassSize = ftell(bytecode); 409 rewind(bytecode); 410 411 if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize, &newClassBytes))) { 412 NSK_COMPLAIN0("buffer couldn't be allocated\n"); 413 return NSK_FALSE; 414 } 415 read_bytes = (jint) fread(newClassBytes, 1, newClassSize, bytecode); 416 fclose(bytecode); 417 if (read_bytes != newClassSize) { 418 NSK_COMPLAIN0("TEST FAILED: error reading file\n"); 419 return NSK_FALSE; 420 } 421 422 return NSK_TRUE; 423 } 424 425 /* ============================================================================= */ 426 427 const char* getThreadName(JNIEnv* jni_env, jthread thread) { 428 jmethodID methodID; 429 jclass klass; 430 jstring jthreadName; 431 const char *threadName; 432 433 strcpy(chbuffer, ""); 434 435 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(thread)) != NULL)) { 436 nsk_jvmti_setFailStatus(); 437 return chbuffer; 438 } 439 440 if (!NSK_JNI_VERIFY(jni_env, (methodID = 441 jni_env->GetMethodID(klass, "getName", "()Ljava/lang/String;")) != NULL)) { 442 nsk_jvmti_setFailStatus(); 443 return chbuffer; 444 } 445 446 jthreadName = (jstring) jni_env->CallObjectMethod(thread, methodID); 447 448 threadName = jni_env->GetStringUTFChars(jthreadName, 0); 449 450 strcpy(chbuffer, threadName); 451 452 jni_env->ReleaseStringUTFChars(jthreadName, threadName); 453 454 return chbuffer; 455 } 456 457 /* ============================================================================= */ 458 459 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object) { 460 461 char *className; 462 char *generic; 463 jclass klass; 464 465 strcpy(chbuffer, ""); 466 467 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(object)) != NULL)) { 468 nsk_jvmti_setFailStatus(); 469 return chbuffer; 470 } 471 472 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, &generic))) { 473 nsk_jvmti_setFailStatus(); 474 return chbuffer; 475 } 476 477 strcpy(chbuffer, className); 478 479 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 480 nsk_jvmti_setFailStatus(); 481 } 482 483 if (generic != NULL) 484 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) { 485 nsk_jvmti_setFailStatus(); 486 } 487 488 return chbuffer; 489 } 490 491 /* ============================================================================= */ 492 493 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread, 494 jmethodID method) { 495 496 jvmtiLocalVariableEntry *table = NULL; 497 jint entryCount = 0; 498 int i; 499 jint value = -1; 500 501 /* getting local variable table*/ 502 if (!NSK_JVMTI_VERIFY(jvmti_env->GetLocalVariableTable(method, &entryCount, &table))) { 503 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n"); 504 } 505 506 if (table != NULL) { 507 jvmtiError error; 508 509 for (i = 0; i < entryCount; i++) { 510 if (strcmp(table[i].name, LOCAL_VARIABLE_NAME) == 0) { 511 error = jvmti_env->GetLocalInt(thread, 0, table[i].slot, &value); 512 if (!NSK_VERIFY(error == JVMTI_ERROR_NONE 513 || error == JVMTI_ERROR_INVALID_SLOT)) 514 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n"); 515 } 516 } 517 518 for (i = 0; i < entryCount; i++) { 519 520 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table[i].name))) { 521 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n"); 522 } 523 524 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table[i].signature))) { 525 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method signature\n\n"); 526 } 527 528 } 529 530 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table))) { 531 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to local variable table\n\n"); 532 } 533 534 } 535 536 return value; 537 } 538 539 /* ============================================================================= */ 540 541 JNIEXPORT void JNICALL 542 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_setThread(JNIEnv *env, 543 jclass cls, jthread thread) { 544 545 if (!NSK_JNI_VERIFY(env, (testClass = (jclass) env->NewGlobalRef(cls)) != NULL)) 546 nsk_jvmti_setFailStatus(); 547 548 if (!NSK_JNI_VERIFY(env, (testedThread = env->NewGlobalRef(thread)) != NULL)) 549 nsk_jvmti_setFailStatus(); 550 551 } 552 553 /* ============================================================================= */ 554 555 JNIEXPORT jboolean JNICALL 556 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_resumeThread(JNIEnv *env, 557 jclass cls, jthread thread) { 558 559 NSK_DISPLAY0("\tresuming thread...\n"); 560 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread); 561 562 if (!NSK_JVMTI_VERIFY(jvmti->ResumeThread(thread))) { 563 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n"); 564 nsk_jvmti_setFailStatus(); 565 return JNI_FALSE; 566 } 567 568 return JNI_TRUE; 569 } 570 571 /* ============================================================================= */ 572 573 JNIEXPORT jboolean JNICALL 574 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_suspendThread(JNIEnv *env, 575 jclass cls, jthread thread) { 576 577 NSK_DISPLAY0("\tsuspending thread...\n"); 578 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread); 579 580 if (!NSK_JVMTI_VERIFY(jvmti->SuspendThread(thread))) { 581 NSK_COMPLAIN0("TEST FAILED: unable to suspend the thread\n"); 582 nsk_jvmti_setFailStatus(); 583 return JNI_FALSE; 584 } 585 586 return JNI_TRUE; 587 } 588 589 /* ============================================================================= */ 590 591 JNIEXPORT jboolean JNICALL 592 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_popFrame(JNIEnv *env, 593 jclass cls, jthread thread) { 594 595 NSK_DISPLAY0("\tpopping frame...\n"); 596 if (!NSK_JVMTI_VERIFY(jvmti->PopFrame(thread))) { 597 NSK_COMPLAIN0("TEST FAILED: unable to pop the currently executed frame\n"); 598 nsk_jvmti_setFailStatus(); 599 return JNI_FALSE; 600 } 601 602 NSK_DISPLAY0("\tresuming thread...\n"); 603 if (!NSK_JVMTI_VERIFY(jvmti->ResumeThread(thread))) { 604 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n"); 605 nsk_jvmti_setFailStatus(); 606 return NSK_FALSE; 607 } 608 609 testStep++; 610 enableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread); 611 612 return JNI_TRUE; 613 } 614 615 /* ============================================================================= */ 616 617 /** Agent library initialization. */ 618 #ifdef STATIC_BUILD 619 JNIEXPORT jint JNICALL Agent_OnLoad_hs201t001(JavaVM *jvm, char *options, void *reserved) { 620 return Agent_Initialize(jvm, options, reserved); 621 } 622 JNIEXPORT jint JNICALL Agent_OnAttach_hs201t001(JavaVM *jvm, char *options, void *reserved) { 623 return Agent_Initialize(jvm, options, reserved); 624 } 625 JNIEXPORT jint JNI_OnLoad_hs201t001(JavaVM *jvm, char *options, void *reserved) { 626 return JNI_VERSION_1_8; 627 } 628 #endif 629 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 630 631 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 632 return JNI_ERR; 633 634 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 635 636 if (!NSK_VERIFY((jvmti = 637 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 638 return JNI_ERR; 639 640 { 641 jvmtiCapabilities caps; 642 memset(&caps, 0, sizeof(caps)); 643 644 caps.can_generate_exception_events = 1; 645 caps.can_generate_breakpoint_events = 1; 646 caps.can_generate_single_step_events = 1; 647 caps.can_access_local_variables = 1; 648 caps.can_redefine_classes = 1; 649 caps.can_pop_frame = 1; 650 caps.can_suspend = 1; 651 652 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 653 return JNI_ERR; 654 } 655 656 { 657 jvmtiEventCallbacks eventCallbacks; 658 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 659 eventCallbacks.ClassLoad = callbackClassLoad; 660 eventCallbacks.Exception = callbackException; 661 eventCallbacks.ExceptionCatch = callbackExceptionCatch; 662 eventCallbacks.Breakpoint = callbackBreakpoint; 663 eventCallbacks.SingleStep = callbackSingleStep; 664 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 665 return JNI_ERR; 666 } 667 668 NSK_DISPLAY0("Enable events\n"); 669 670 enableEvent(jvmti, JVMTI_EVENT_CLASS_LOAD, testedThread); 671 enableEvent(jvmti, JVMTI_EVENT_BREAKPOINT, testedThread); 672 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION, testedThread); 673 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION_CATCH, testedThread); 674 675 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 676 return JNI_ERR; 677 678 return JNI_OK; 679 } 680 681 /* ============================================================================= */ 682 683 }