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             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))) {
 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 not 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 not 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) {
 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) {
 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/%s.class",
 396                 pathToByteCode, "newclass", 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_hs201t002_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_hs201t002_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 NSK_FALSE;
 566     }
 567 
 568     return NSK_TRUE;
 569 }
 570 
 571 /* ============================================================================= */
 572 
 573 JNIEXPORT jboolean JNICALL
 574 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t002_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 NSK_FALSE;
 584     }
 585 
 586     return NSK_TRUE;
 587 }
 588 
 589 /* ============================================================================= */
 590 
 591 JNIEXPORT jboolean JNICALL
 592 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t002_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 NSK_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 NSK_TRUE;
 613 }
 614 
 615 /* ============================================================================= */
 616 
 617 /** Agent library initialization. */
 618 #ifdef STATIC_BUILD
 619 JNIEXPORT jint JNICALL Agent_OnLoad_hs201t002(JavaVM *jvm, char *options, void *reserved) {
 620     return Agent_Initialize(jvm, options, reserved);
 621 }
 622 JNIEXPORT jint JNICALL Agent_OnAttach_hs201t002(JavaVM *jvm, char *options, void *reserved) {
 623     return Agent_Initialize(jvm, options, reserved);
 624 }
 625 JNIEXPORT jint JNI_OnLoad_hs201t002(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 }