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