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 /*
  25  *
  26  * JVMTI agent used for run every test from the testbase in a special
  27  * debug mode. This mode is intended to be part of serviceability
  28  * reliability testing.
  29  */
  30 
  31 #include <stdio.h>
  32 #include <stdlib.h>
  33 #include <stdarg.h>
  34 #include <string.h>
  35 #include <jvmti.h>
  36 
  37 #include "nsk_tools.h"
  38 #include "jni_tools.h"
  39 #include "JVMTITools.h"
  40 #include "jvmti_tools.h"
  41 
  42 extern "C" {
  43 
  44 static jvmtiEnv *jvmti = NULL; /* JVMTI env */
  45 static jvmtiEventCallbacks callbacks;
  46 static jrawMonitorID eventLock; /* raw monitor used for exclusive ownership of HotSwap function */
  47 
  48 static volatile int debug_mode = 0; /* 0 - verbose mode off;
  49                                        1 - verbose mode on;
  50                                        2 - verbose mode on including all JVMTI events reporting,
  51                                            produces a huge number of messages */
  52 
  53 /* stress level */
  54 static volatile int stress_lev = 0; /* 0 - default mode: generation of all events except
  55                                                 ExceptionCatch,
  56                                                 MethodEntry/Exit, SingleStep;
  57                                        1 - generation of all events except
  58                                                 MethodEntry/Exit,
  59                                                 SingleStep;
  60                                        2 - generation of all events except
  61                                                 SingleStep;
  62                                        3 - generation of all events, including
  63                                                 ExceptionCatch,
  64                                                 MethodEntry/Exit,
  65                                                 SingleStep
  66                                      */
  67 
  68 #define TRUE 1
  69 #define FALSE 0
  70 
  71 /**** the following is used for "postVM_DEATH" events watching ****/
  72 static volatile int vm_death_occured = FALSE;
  73 /************************************************/
  74 
  75 /**** the following is used for HotSwap mode ****/
  76 
  77 /* HotSwap modes:
  78  HOTSWAP_OFF                - default mode: HotSwap off;
  79  HOTSWAP_EVERY_METHOD_ENTRY - HotSwap tested class in every method entry event
  80                               of running test
  81  HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS - HotSwap tested class in every
  82                               method entry event of every class
  83  HOTSWAP_EVERY_SINGLE_STEP  - HotSwap tested class in every single step event
  84                               of running test
  85  HOTSWAP_EVERY_EXCEPTION    - HotSwap tested class in every exception event
  86                               of running test
  87  HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS - HotSwap tested class in every
  88                               exception event of every class
  89  */
  90 
  91 #define HOTSWAP_OFF 0
  92 #define HOTSWAP_EVERY_METHOD_ENTRY 2
  93 #define HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS 20
  94 #define HOTSWAP_EVERY_SINGLE_STEP 3
  95 #define HOTSWAP_EVERY_EXCEPTION 4
  96 #define HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS 40
  97 
  98 static int hotswap = HOTSWAP_OFF;
  99 
 100 typedef struct {   /* test class info */
 101     char *clazzsig;  /* class signature */
 102     jclass cls;      /* a class to be redefined */
 103     jint bCount;     /* number of bytes defining the class */
 104     jbyte *clsBytes; /* bytes defining the class */
 105     struct class_info *next;
 106 } class_info;
 107 
 108 
 109 static const char *shortTestName = NULL; /* name of the test without package prefix */
 110 static jclass rasCls; /* reference to the auxiliary class RASagent used for HotSwap */
 111 static class_info *clsInfo = NULL, *clsInfoFst = NULL;
 112 
 113 static void lock(JNIEnv*);
 114 static void unlock(JNIEnv*);
 115 static jint allocClsInfo(JNIEnv*, char*, jclass);
 116 static void deallocClsInfo(JNIEnv*);
 117 static int findAndHotSwap(JNIEnv*, jclass);
 118 static int doHotSwap(JNIEnv*, jclass, jint, jbyte*);
 119 static void display(int, const char format[], ...);
 120 static void clearJavaException(JNIEnv*);
 121 static int enableEventsCaps();
 122 static int addStressEvents();
 123 static void getVerdict(JNIEnv*, const char *);
 124 /************************************************/
 125 
 126 /** callback functions **/
 127 void JNICALL
 128 Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr, jmethodID method,
 129         jlocation loc) {
 130 
 131     display(1, "#### JVMTIagent: Breakpoint occurred ####\n");
 132 
 133     getVerdict(jni_env, "Breakpoint");
 134 }
 135 
 136 void JNICALL
 137 ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 138         jclass class_beeing_redefined,
 139         jobject loader, const char* name, jobject protection_domain,
 140         jint class_data_len, const unsigned char* class_data,
 141         jint *new_class_data_len, unsigned char** new_class_data) {
 142 
 143     display(1, "#### JVMTIagent: ClassFileLoadHook occurred ####\n");
 144 
 145     getVerdict(jni_env, "ClassFileLoadHook");
 146 }
 147 
 148 void JNICALL
 149 ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread, jclass klass) {
 150     char *cls_sig;
 151     jint clsByteCount;
 152 
 153     display((hotswap != HOTSWAP_OFF)?0:1,
 154         "#### JVMTIagent: ClassLoad occurred ####\n");
 155 
 156     getVerdict(jni_env, "ClassLoad");
 157 
 158     if (hotswap != HOTSWAP_OFF) {
 159         /* enter into a raw monitor for exclusive work with redefined class */
 160         lock(jni_env);
 161         display(0, "#### JVMTIagent: ClassLoad: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");
 162 
 163         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature,
 164                 jvmti_env, klass, &cls_sig, /*&generic*/NULL)))
 165             NSK_CPP_STUB2(FatalError, jni_env,
 166                 "JVMTIagent: failed to get class signature\n");
 167         else {
 168             if (shortTestName != NULL) {
 169                 if (strstr((const char*) cls_sig, shortTestName) != NULL) {
 170                     display(0, "#### JVMTIagent: found test class matched with \"%s\"\n\
 171 <JVMTIagent>\tsignature=%s\n",
 172                         shortTestName, cls_sig);
 173                     clsByteCount = allocClsInfo(jni_env, cls_sig, klass);
 174                     display(0, "#### JVMTIagent: %d bytes defining the class have been successfully loaded\n",
 175                         clsByteCount);
 176                 }
 177             }
 178         }
 179 
 180         /* exit from the raw monitor */
 181         unlock(jni_env);
 182         display(0, "#### JVMTIagent: ClassLoad: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");
 183     }
 184 }
 185 
 186 void JNICALL
 187 ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 188         jthread thr, jclass cls) {
 189 
 190     display(1, "#### JVMTIagent: ClassPrepare occurred ####\n");
 191 
 192     getVerdict(jni_env, "ClassPrepare");
 193 }
 194 
 195 void JNICALL
 196 CompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size,
 197         const void* code_addr,  jint map_length,
 198         const jvmtiAddrLocationMap* map, const void* compile_info) {
 199 
 200     display(1, "#### JVMTIagent: CompiledMethodLoad occurred ####\n");
 201 
 202     getVerdict(NULL, "CompiledMethodLoad");
 203 }
 204 
 205 void JNICALL
 206 CompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method,
 207         const void* code_addr) {
 208 
 209     display(1, "#### JVMTIagent: CompiledMethodUnload occurred ####\n");
 210 
 211     getVerdict(NULL, "CompiledMethodUnload");
 212 }
 213 
 214 void JNICALL
 215 DataDumpRequest(jvmtiEnv *jvmti_env) {
 216 
 217     display(1, "#### JVMTIagent: DataDumpRequest occurred ####\n");
 218 
 219     getVerdict(NULL, "DataDumpRequest");
 220 }
 221 
 222 void JNICALL
 223 DynamicCodeGenerated(jvmtiEnv *jvmti_env,
 224         const char* name,
 225         const void* address,
 226         jint length) {
 227 
 228     display(1, "#### JVMTIagent: DynamicCodeGenerated occurred ####\n");
 229 
 230     getVerdict(NULL, "DynamicCodeGenerated");
 231 }
 232 
 233 void JNICALL
 234 Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,
 235         jmethodID method, jlocation location, jobject exception,
 236         jmethodID catch_method, jlocation catch_location) {
 237     jclass decl_clazz;
 238 
 239     display((hotswap == HOTSWAP_EVERY_EXCEPTION ||
 240             hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS)?0:1,
 241         "#### JVMTIagent: Exception occurred ####\n");
 242 
 243     getVerdict(jni_env, "Exception");
 244 
 245     if (hotswap == HOTSWAP_EVERY_EXCEPTION ||
 246             hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
 247         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
 248                 jvmti_env, method, &decl_clazz)))
 249             NSK_CPP_STUB2(FatalError, jni_env,
 250                 "JVMTIagent: failed to get method declaring class\n");
 251 
 252         if (findAndHotSwap(jni_env, decl_clazz) != 0)
 253             NSK_CPP_STUB2(FatalError, jni_env,
 254                 "JVMTIagent: failed to hotswap class\n");
 255     }
 256 }
 257 
 258 void JNICALL
 259 FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 260         jthread thr, jmethodID method,
 261         jlocation location, jclass field_klass, jobject obj, jfieldID field) {
 262 
 263     display(1, "#### JVMTIagent: FieldAccess occurred ####\n");
 264 
 265     getVerdict(jni_env, "FieldAccess");
 266 }
 267 
 268 void JNICALL
 269 FieldModification(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 270         jthread thr, jmethodID method, jlocation location,
 271         jclass field_klass, jobject obj,
 272         jfieldID field, char sig, jvalue new_value) {
 273 
 274     display(1, "#### JVMTIagent: FieldModification occurred ####\n");
 275 
 276     getVerdict(jni_env, "FieldModification");
 277 }
 278 
 279 void JNICALL
 280 FramePop(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 281         jthread thr, jmethodID method, jboolean wasPopedByException) {
 282 
 283     display(1, "#### JVMTIagent: FramePop occurred ####\n");
 284 
 285     getVerdict(jni_env, "FramePop");
 286 }
 287 
 288 void JNICALL
 289 GarbageCollectionFinish(jvmtiEnv *jvmti_env) {
 290 
 291     display(1, "#### JVMTIagent: GarbageCollectionFinish occurred ####\n");
 292 
 293     getVerdict(NULL, "GarbageCollectionFinish");
 294 }
 295 
 296 void JNICALL
 297 GarbageCollectionStart(jvmtiEnv *jvmti_env) {
 298 
 299     display(1, "#### JVMTIagent: GarbageCollectionStart occurred ####\n");
 300 
 301     getVerdict(NULL, "GarbageCollectionStart");
 302 }
 303 
 304 void JNICALL
 305 MonitorContendedEnter(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,
 306         jobject obj) {
 307 
 308     display(1, "#### JVMTIagent: MonitorContendedEnter occurred ####\n");
 309 
 310     getVerdict(jni_env, "MonitorContendedEnter");
 311 }
 312 
 313 void JNICALL
 314 MonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,
 315         jobject obj) {
 316 
 317     display(1, "#### JVMTIagent: MonitorContendedEntered occurred ####\n");
 318 
 319     getVerdict(jni_env, "MonitorContendedEntered");
 320 }
 321 
 322 void JNICALL
 323 MonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr, jobject obj,
 324         jlong tout) {
 325 
 326     display(1, "#### JVMTIagent: MonitorWait occurred ####\n");
 327 
 328     getVerdict(jni_env, "MonitorWait");
 329 }
 330 
 331 void JNICALL
 332 MonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env,
 333         jthread thr, jobject obj, jboolean timed_out) {
 334 
 335     display(1, "#### JVMTIagent: MonitorWaited occurred ####\n");
 336 
 337     getVerdict(jni_env, "MonitorWaited");
 338 }
 339 
 340 void JNICALL
 341 NativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
 342         jmethodID method, void *addr, void **new_addr) {
 343 
 344     display(1, "#### JVMTIagent: NativeMethodBind occurred ####\n");
 345 
 346     getVerdict(jni_env, "NativeMethodBind");
 347 }
 348 
 349 void JNICALL
 350 ObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
 351 
 352     display(1, "#### JVMTIagent: ObjectFree occurred ####\n");
 353 
 354     getVerdict(NULL, "ObjectFree");
 355 }
 356 
 357 void JNICALL
 358 ThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
 359 
 360     display(1, "#### JVMTIagent: ThreadEnd occurred ####\n");
 361 
 362     getVerdict(jni_env, "ThreadEnd");
 363 }
 364 
 365 void JNICALL
 366 ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
 367 
 368     display(1, "#### JVMTIagent: ThreadStart occurred ####\n");
 369 
 370     getVerdict(jni_env, "ThreadStart");
 371 }
 372 
 373 void JNICALL
 374 VMDeath(jvmtiEnv *jvmti_env, JNIEnv *jni_env) {
 375     vm_death_occured = TRUE;
 376 
 377     display(0, "#### JVMTIagent: VMDeath occurred ####\n");
 378 
 379     if (hotswap != HOTSWAP_OFF) {
 380         deallocClsInfo(jni_env);
 381         display(0, "#### JVMTIagent: allocated memory was successfully freed ####\n");
 382     }
 383 }
 384 
 385 void JNICALL
 386 VMInit(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr) {
 387 
 388     display(0, "#### JVMTIagent: VMInit occurred ####\n");
 389 
 390     getVerdict(jni_env, "VMInit");
 391 }
 392 
 393 void JNICALL
 394 VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
 395 
 396     display(0, "#### JVMTIagent: VMStart occurred ####\n");
 397 
 398     getVerdict(jni_env, "VMStart");
 399 }
 400 
 401 JNIEXPORT void JNICALL
 402 VMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
 403         jobject object, jclass object_klass, jlong size) {
 404 
 405     display(1, "#### JVMTIagent: VMObjectAlloc occurred ####\n");
 406 
 407     getVerdict(jni_env, "VMObjectAlloc");
 408 }
 409 
 410 void JNICALL
 411 SingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
 412         jmethodID method, jlocation location) {
 413     jclass decl_clazz;
 414 
 415     display((hotswap == HOTSWAP_EVERY_SINGLE_STEP)?0:1,
 416         "#### JVMTIagent: SingleStep occurred ####\n");
 417 
 418     getVerdict(jni_env, "SingleStep");
 419 
 420     if (hotswap == HOTSWAP_EVERY_SINGLE_STEP) {
 421         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
 422                 jvmti_env, method, &decl_clazz)))
 423             NSK_CPP_STUB2(FatalError, jni_env,
 424                 "JVMTIagent: failed to get method declaring class\n");
 425 
 426         if (findAndHotSwap(jni_env, decl_clazz) != 0)
 427             NSK_CPP_STUB2(FatalError, jni_env,
 428                 "JVMTIagent: failed to hotswap class\n");
 429     }
 430 }
 431 
 432 void JNICALL
 433 MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 434         jthread thr, jmethodID method) {
 435     jclass decl_clazz;
 436 
 437     display((hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||
 438             hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS)?0:1,
 439         "#### JVMTIagent: MethodEntry occurred ####\n");
 440 
 441     getVerdict(jni_env, "MethodEntry");
 442 
 443     if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||
 444             hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS) {
 445         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
 446                 jvmti_env, method, &decl_clazz)))
 447             NSK_CPP_STUB2(FatalError, jni_env,
 448                 "JVMTIagent: failed to get method declaring class\n");
 449 
 450         if (findAndHotSwap(jni_env, decl_clazz) != 0)
 451             NSK_CPP_STUB2(FatalError, jni_env,
 452                 "JVMTIagent: failed to hotswap class\n");
 453     }
 454 }
 455 
 456 void JNICALL
 457 MethodExit(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
 458         jthread thr, jmethodID method,
 459         jboolean was_poped_by_exc, jvalue return_value) {
 460 
 461     display(1, "#### JVMTIagent: MethodExit occurred ####\n");
 462 
 463     getVerdict(jni_env, "MethodExit");
 464 }
 465 
 466 void JNICALL
 467 ExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,
 468         jmethodID method, jlocation location, jobject exception) {
 469     jclass decl_clazz;
 470 
 471     display((hotswap == HOTSWAP_EVERY_EXCEPTION ||
 472             hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS)?0:1,
 473         "#### JVMTIagent: ExceptionCatch occurred ####\n");
 474 
 475     getVerdict(jni_env, "ExceptionCatch");
 476 
 477     if (hotswap == HOTSWAP_EVERY_EXCEPTION ||
 478             hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
 479         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
 480                 jvmti_env, method, &decl_clazz)))
 481             NSK_CPP_STUB2(FatalError, jni_env,
 482                 "JVMTIagent: failed to get method declaring class\n");
 483 
 484         if (findAndHotSwap(jni_env, decl_clazz) != 0)
 485             NSK_CPP_STUB2(FatalError, jni_env,
 486                 "JVMTIagent: failed to hotswap class\n");
 487     }
 488 }
 489 /************************/
 490 
 491 static void lock(JNIEnv *jni_env) {
 492     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter,
 493             jvmti, eventLock)))
 494         NSK_CPP_STUB2(FatalError, jni_env,
 495             "JVMTIagent: failed to enter a raw monitor\n");
 496 }
 497 
 498 static void unlock(JNIEnv *jni_env) {
 499     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit,
 500             jvmti, eventLock)))
 501         NSK_CPP_STUB2(FatalError, jni_env,
 502             "JVMTIagent: failed to exit a raw monitor\n");
 503 }
 504 
 505 JNIEXPORT jint JNICALL
 506 Java_nsk_share_RASagent_setHotSwapMode(JNIEnv *jni_env, jclass cls,
 507         jboolean vrb, jint level, jstring shortName) {
 508     jvmtiCapabilities capabil;
 509     jmethodID mid = NULL;
 510 
 511     if (jvmti == NULL) {
 512         printf("ERROR(%s,%d): JVMTIagent was not properly loaded: JVMTI env = NULL\n",
 513                __FILE__, __LINE__);
 514         return 1;
 515     }
 516 
 517     /* get supported JVMTI capabilities */
 518     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities,
 519             jvmti, &capabil)))
 520         NSK_CPP_STUB2(FatalError, jni_env,
 521             "JVMTIagent: failed to get capabilities\n");
 522     if (capabil.can_redefine_classes != 1) { /* ???????????? */
 523         printf("ERROR: JVMTIagent: Class File Redefinition (HotSwap) is not implemented in this VM\n");
 524         return 1;
 525     }
 526 
 527     if (vrb == JNI_TRUE && debug_mode == 0)
 528         debug_mode = 1;
 529 
 530     hotswap = level;
 531     switch (hotswap) {
 532         case HOTSWAP_OFF:
 533             display(0, "#### JVMTIagent: hotswap mode off ####\n");
 534             return 0;
 535         case HOTSWAP_EVERY_METHOD_ENTRY:
 536             stress_lev = 2;
 537             display(0, "#### JVMTIagent: hotswapping class in every method entry event enabled ####\n\
 538 <JVMTIagent>\tHotSwap stress level: %d\n",
 539                 stress_lev);
 540             break;
 541         case HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS:
 542             stress_lev = 2;
 543             display(0, "#### JVMTIagent: hotswapping class in every method entry event for every class enabled ####\n\
 544 <JVMTIagent>\tHotSwap stress level: %d\n",
 545                 stress_lev);
 546             break;
 547         case HOTSWAP_EVERY_SINGLE_STEP:
 548             stress_lev = 3;
 549             display(0, "#### JVMTIagent: hotswapping class in every single step event enabled ####\n\
 550 <JVMTIagent>\tHotSwap stress level: %d\n",
 551                 stress_lev);
 552             break;
 553         case HOTSWAP_EVERY_EXCEPTION:
 554             stress_lev = 4;
 555             display(0, "#### JVMTIagent: hotswapping class in every exception event enabled ####\n\
 556 <JVMTIagent>\tHotSwap stress level: %d\n",
 557                 stress_lev);
 558             break;
 559         case HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS:
 560             stress_lev = 40;
 561             display(0, "#### JVMTIagent: hotswapping class in every exception event for every class enabled ####\n\
 562 <JVMTIagent>\tHotSwap stress level: %d\n",
 563                 stress_lev);
 564             break;
 565         default:
 566             printf("ERROR(%s,%d): JVMTIagent: unknown value of HotSwap stress level: \"%d\"\n",
 567                 __FILE__,__LINE__,hotswap);
 568             return 1;
 569     }
 570 
 571     if (!NSK_JNI_VERIFY(jni_env, (shortTestName = NSK_CPP_STUB3(GetStringUTFChars,
 572             jni_env, shortName, NULL)) != NULL)) {
 573         printf("ERROR: JVMTIagent: unable to get UTF-8 characters of the string\n");
 574         return 1;
 575     }
 576     display(0, "#### JVMTIagent: short name of current test is \"%s\"\n",
 577         shortTestName);
 578 
 579     if (!NSK_JNI_VERIFY(jni_env, (rasCls = NSK_CPP_STUB2(NewGlobalRef,
 580             jni_env, cls)) != NULL)) {
 581         printf("ERROR JVMTIagent: unable to create a new global reference of the class \"RASagent\"\n");
 582         return 1;
 583     }
 584 
 585     if (addStressEvents() != 0) {
 586         printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",
 587             __FILE__,__LINE__);
 588         return 1;
 589     }
 590 
 591     return 0;
 592 }
 593 
 594 static jint allocClsInfo(JNIEnv *jni_env, char *cls_sig, jclass clazz) {
 595     class_info *_clsInfo = NULL;
 596     jmethodID mid = NULL;
 597     jbyteArray classBytes;
 598     jboolean isCopy;
 599 
 600     if ((_clsInfo = (class_info*)
 601             malloc(sizeof(class_info))) == NULL)
 602         NSK_CPP_STUB2(FatalError, jni_env,
 603             "JVMTIagent: cannot allocate memory for class_info\n");
 604 
 605     /* fill the structure class_info */
 606     _clsInfo->clazzsig = cls_sig;
 607 
 608     if (!NSK_JNI_VERIFY(jni_env, ((*_clsInfo).cls = NSK_CPP_STUB2(NewGlobalRef,
 609             jni_env, clazz)) != NULL)) {
 610         printf("ERROR: JVMTIagent: unable to create a new global reference of class \"%s\"\n",
 611             _clsInfo->clazzsig);
 612         free(_clsInfo);
 613         deallocClsInfo(jni_env);
 614         NSK_CPP_STUB2(FatalError, jni_env,
 615             "JVMTIagent: unable to create a new global reference of class\n");
 616     }
 617 
 618     if (!NSK_JNI_VERIFY(jni_env, (mid =
 619         NSK_CPP_STUB4(GetStaticMethodID, jni_env, rasCls,
 620             "loadFromClassFile", "(Ljava/lang/String;)[B")) != NULL))
 621         NSK_CPP_STUB2(FatalError, jni_env,
 622             "JVMTIagent: unable to get ID of the method \"loadFromClassFile\"\n");
 623 
 624     classBytes = (jbyteArray) NSK_CPP_STUB4(CallStaticObjectMethod,
 625         jni_env, rasCls, mid, NSK_CPP_STUB2(NewStringUTF, jni_env, cls_sig));
 626 
 627     clearJavaException(jni_env);
 628 
 629     (*_clsInfo).bCount = NSK_CPP_STUB2(GetArrayLength, jni_env, classBytes);
 630 
 631     (*_clsInfo).clsBytes =
 632         NSK_CPP_STUB3(GetByteArrayElements, jni_env, classBytes, &isCopy);
 633 
 634     _clsInfo->next = NULL;
 635 
 636     if (clsInfo != NULL) {
 637         clsInfo->next = (struct class_info*) _clsInfo;
 638     }
 639     else {
 640         clsInfoFst = _clsInfo;
 641     }
 642     clsInfo = _clsInfo;
 643 
 644     return (*_clsInfo).bCount;
 645 }
 646 
 647 static void deallocClsInfo(JNIEnv *jni_env) {
 648     class_info *clsInfoCurr = clsInfoFst;
 649 
 650     NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni_env, rasCls));
 651 
 652     while(clsInfoCurr != NULL) {
 653         class_info *_clsInfo = clsInfoCurr;
 654 
 655         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
 656                 jvmti, (unsigned char*) clsInfoCurr->clazzsig)))
 657             NSK_CPP_STUB2(FatalError, jni_env,
 658                 "JVMTIagent: failed to deallocate memory for clazzsig\n");
 659 
 660         NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni_env, clsInfoCurr->cls));
 661 
 662         clsInfoCurr = (class_info*) clsInfoCurr->next;
 663 
 664         free(_clsInfo);
 665     }
 666     /* fix for 4756585: indicate that stucture class_info is empty now */
 667     clsInfoFst = NULL;
 668 }
 669 
 670 static int findAndHotSwap(JNIEnv *jni_env, jclass clazz) {
 671     int ret_code = 0;
 672     char *clazzsig = NULL;
 673     class_info *clsInfoCurr = clsInfoFst;
 674 
 675     display(1, "\n#### JVMTIagent: findAndHotSwap: obtaining class signature of class to be hotswap ...\n");
 676     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature,
 677             jvmti, clazz, &clazzsig, /*&generic*/NULL)))
 678         NSK_CPP_STUB2(FatalError, jni_env,
 679             "JVMTIagent: findAndHotSwap: failed to get class signature\n");
 680     else {
 681         display(1, "#### JVMTIagent: findAndHotSwap: ... class signature obtained: \"%s\"\n",
 682             clazzsig);
 683 
 684         /* enter into a raw monitor for exclusive work with redefined class */
 685         lock(jni_env);
 686         display(0, "#### JVMTIagent: findAndHotSwap: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");
 687 
 688         while(clsInfoCurr != NULL) {
 689             if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS ||
 690                     hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
 691                 display(1, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" during execution of class \"%s\" ...\n",
 692                     clsInfoCurr->clazzsig, clazzsig);
 693                 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
 694                         jvmti, (unsigned char*) clazzsig)))
 695                     NSK_CPP_STUB2(FatalError, jni_env,
 696                         "JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");
 697 
 698                 if (doHotSwap(jni_env, clsInfoCurr->cls,
 699                         clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {
 700                     ret_code = 1;
 701                     break;
 702                 }
 703             }
 704             else {
 705                 if (strcmp(clazzsig, clsInfoCurr->clazzsig) == 0) {
 706                     display(0, "\n#### JVMTIagent: findAndHotSwap: tested class found \"%s\" ...\n",
 707                         clazzsig);
 708 
 709                     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
 710                             jvmti, (unsigned char*) clazzsig)))
 711                         NSK_CPP_STUB2(FatalError, jni_env,
 712                             "JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");
 713 
 714                     display(0, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" ...\n",
 715                         clsInfoCurr->clazzsig);
 716                     if (doHotSwap(jni_env, clsInfoCurr->cls,
 717                             clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {
 718                         ret_code = 1;
 719                         break;
 720                     }
 721                 }
 722             }
 723 
 724             clsInfoCurr = (class_info*) clsInfoCurr->next;
 725         }
 726 
 727         /* exit raw monitor */
 728         unlock(jni_env);
 729         display(0, "#### JVMTIagent: findAndHotSwap: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");
 730     }
 731 
 732     return ret_code;
 733 }
 734 
 735 static int doHotSwap(JNIEnv *jni_env, jclass redefCls, jint bCount,
 736         jbyte *classBytes) {
 737     jvmtiClassDefinition classDef;
 738 
 739     /* fill the structure jvmtiClassDefinition */
 740     classDef.klass = redefCls;
 741     classDef.class_byte_count = bCount;
 742     classDef.class_bytes = (unsigned char*) classBytes;
 743 
 744     display(0, "#### JVMTIagent: >>>>>>>> Invoke RedefineClasses():\n\
 745 <JVMTIagent>\tnew class byte count=%d\n",
 746         classDef.class_byte_count);
 747     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RedefineClasses,
 748             jvmti, 1, &classDef)))
 749         return 1;
 750 
 751     display(0, "#### JVMTIagent: <<<<<<<< RedefineClasses() is successfully done ####\n");
 752 
 753     return 0;
 754 }
 755 
 756 static int addStressEvents() {
 757     static int stepEventSet = JNI_FALSE;
 758     static int methodsEventSet = JNI_FALSE;
 759     static int excCatchEventSet = JNI_FALSE;
 760 
 761     if (stress_lev >= 3) {
 762         /* SingleStep events */
 763         if (stepEventSet == JNI_FALSE) { /* don't set the event twice */
 764             display(0, "#### JVMTIagent: setting SingleStep events ...\n");
 765 
 766             callbacks.SingleStep = &SingleStep;
 767 
 768             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 769                     jvmti, JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, NULL)))
 770                 return JNI_ERR;
 771 
 772             stepEventSet = JNI_TRUE;
 773 
 774             display(0, "#### JVMTIagent: ... setting SingleStep events done\n");
 775         }
 776     }
 777 
 778     if (stress_lev >= 2) {
 779         /* MethodEntry/Exit events */
 780         if (methodsEventSet == JNI_FALSE) { /* don't set the event twice */
 781             display(0, "#### JVMTIagent: setting MethodEntry events ...\n");
 782 
 783             callbacks.MethodEntry = &MethodEntry;
 784 
 785             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 786                     jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL)))
 787                 return JNI_ERR;
 788 
 789             display(0, "#### JVMTIagent: ... setting MethodEntry events done\n");
 790 
 791             /* MethodExit events */
 792             display(0, "#### JVMTIagent: setting MethodExit events ...\n");
 793 
 794             callbacks.MethodExit = &MethodExit;
 795 
 796             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 797                     jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL)))
 798                 return JNI_ERR;
 799 
 800             display(0, "#### JVMTIagent: ... setting MethodExit events done\n");
 801 
 802             methodsEventSet = JNI_TRUE;
 803         }
 804     }
 805 
 806     if (stress_lev >= 1) {
 807         /* ExceptionCatch events */
 808         if (excCatchEventSet == JNI_FALSE) { /* don't set the event twice */
 809             display(0, "#### JVMTIagent: setting ExceptionCatch events ...\n");
 810 
 811             callbacks.ExceptionCatch = &ExceptionCatch;
 812 
 813             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 814                     jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION_CATCH, NULL)))
 815                 return JNI_ERR;
 816 
 817             excCatchEventSet = JNI_TRUE;
 818 
 819             display(0, "#### JVMTIagent: ... setting ExceptionCatch events done\n");
 820         }
 821     }
 822 
 823     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks,
 824             jvmti, &callbacks, sizeof(callbacks))))
 825         return JNI_ERR;
 826     else
 827         return 0;
 828 }
 829 
 830 static int enableEventsCaps() {
 831     jvmtiCapabilities caps;
 832 
 833     memset(&caps, 0, sizeof(jvmtiCapabilities));
 834 
 835     /* add all capabilities */
 836     caps.can_redefine_classes = 1;
 837     caps.can_generate_breakpoint_events = 1;
 838     caps.can_generate_all_class_hook_events = 1;
 839     caps.can_generate_single_step_events = 1;
 840     caps.can_generate_method_entry_events = 1;
 841     caps.can_generate_method_exit_events = 1;
 842     caps.can_generate_exception_events = 1;
 843     caps.can_generate_compiled_method_load_events = 1;
 844     caps.can_generate_field_access_events = 1;
 845     caps.can_generate_field_modification_events = 1;
 846     caps.can_generate_frame_pop_events = 1;
 847     caps.can_generate_garbage_collection_events = 1;
 848     caps.can_generate_monitor_events = 1;
 849     caps.can_generate_native_method_bind_events = 1;
 850     caps.can_generate_object_free_events = 1;
 851     caps.can_generate_vm_object_alloc_events = 1;
 852     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities,
 853             jvmti, &caps)))
 854         return JNI_ERR;
 855 
 856     /* Breakpoint events */
 857     display(0, "#### JVMTIagent: setting Breakpoint events ...\n");
 858 
 859     callbacks.Breakpoint = &Breakpoint;
 860 
 861     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 862             jvmti, JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
 863         return JNI_ERR;
 864     display(0, "#### JVMTIagent: ... setting Breakpoint events done\n");
 865 
 866     /* ClassFileLoadHook events */
 867     display(0, "#### JVMTIagent: setting ClassFileLoadHook events ...\n");
 868 
 869     callbacks.ClassFileLoadHook = &ClassFileLoadHook;
 870 
 871     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 872             jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)))
 873         return JNI_ERR;
 874     display(0, "#### JVMTIagent: ... setting ClassFileLoadHook events done\n");
 875 
 876     /* ClassLoad events */
 877     display(0, "#### JVMTIagent: setting ClassLoad events ...\n");
 878 
 879     callbacks.ClassLoad = &ClassLoad;
 880 
 881     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 882             jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
 883         return JNI_ERR;
 884     display(0, "#### JVMTIagent: ... setting ClassLoad events done\n");
 885 
 886     /* ClassPrepare events */
 887     display(0, "#### JVMTIagent: setting ClassPrepare events ...\n");
 888 
 889     callbacks.ClassPrepare = &ClassPrepare;
 890 
 891     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 892             jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL)))
 893         return JNI_ERR;
 894     display(0, "#### JVMTIagent: ... setting ClassPrepare events done\n");
 895 
 896     /* CompiledMethodLoad events */
 897     display(0, "#### JVMTIagent: setting CompiledMethodLoad events ...\n");
 898 
 899     callbacks.CompiledMethodLoad = &CompiledMethodLoad;
 900 
 901     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 902             jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL)))
 903         return JNI_ERR;
 904     display(0, "#### JVMTIagent: ... setting CompiledMethodLoad events done\n");
 905 
 906     /* CompiledMethodUnload events */
 907     display(0, "#### JVMTIagent: setting CompiledMethodUnload events ...\n");
 908 
 909     callbacks.CompiledMethodUnload = &CompiledMethodUnload;
 910 
 911     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 912             jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL)))
 913         return JNI_ERR;
 914     display(0, "#### JVMTIagent: ... setting CompiledMethodUnload events done\n");
 915 
 916     /* DataDumpRequest events */
 917     display(0, "#### JVMTIagent: setting DataDumpRequest events ...\n");
 918 
 919     callbacks.DataDumpRequest = &DataDumpRequest;
 920 
 921     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 922             jvmti, JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, NULL)))
 923         return JNI_ERR;
 924     display(0, "#### JVMTIagent: ... setting DataDumpRequest events done\n");
 925 
 926     /* DynamicCodeGenerated events */
 927     display(0, "#### JVMTIagent: setting DynamicCodeGenerated events ...\n");
 928 
 929     callbacks.DynamicCodeGenerated = &DynamicCodeGenerated;
 930 
 931     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 932             jvmti, JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL)))
 933         return JNI_ERR;
 934     display(0, "#### JVMTIagent: ... setting DynamicCodeGenerated events done\n");
 935 
 936     /* Exception events */
 937     display(0, "#### JVMTIagent: setting Exception events ...\n");
 938 
 939     callbacks.Exception = &Exception;
 940 
 941     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 942             jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)))
 943         return JNI_ERR;
 944     display(0, "#### JVMTIagent: ... setting Exception events done\n");
 945 
 946     /* FieldAccess events */
 947     display(0, "#### JVMTIagent: setting FieldAccess events ...\n");
 948 
 949     callbacks.FieldAccess = &FieldAccess;
 950 
 951     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 952             jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIELD_ACCESS, NULL)))
 953         return JNI_ERR;
 954     display(0, "#### JVMTIagent: ... setting FieldAccess events done\n");
 955 
 956     /* FieldModification events */
 957     display(0, "#### JVMTIagent: setting FieldModification events ...\n");
 958 
 959     callbacks.FieldModification = &FieldModification;
 960 
 961     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 962             jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIELD_MODIFICATION, NULL)))
 963         return JNI_ERR;
 964     display(0, "#### JVMTIagent: ... setting FieldModification events done\n");
 965 
 966     /* FramePop events */
 967     display(0, "#### JVMTIagent: setting FramePop events ...\n");
 968 
 969     callbacks.FramePop = &FramePop;
 970 
 971     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 972             jvmti, JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, NULL)))
 973         return JNI_ERR;
 974     display(0, "#### JVMTIagent: ... setting FramePop events done\n");
 975 
 976     /* GarbageCollectionFinish events */
 977     display(0, "#### JVMTIagent: setting GarbageCollectionFinish events ...\n");
 978 
 979     callbacks.GarbageCollectionFinish = &GarbageCollectionFinish;
 980 
 981     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 982             jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL)))
 983         return JNI_ERR;
 984     display(0, "#### JVMTIagent: ... setting GarbageCollectionFinish events done\n");
 985 
 986     /* GarbageCollectionStart events */
 987     display(0, "#### JVMTIagent: setting GarbageCollectionStart events ...\n");
 988 
 989     callbacks.GarbageCollectionStart = &GarbageCollectionStart;
 990 
 991     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 992             jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL)))
 993         return JNI_ERR;
 994     display(0, "#### JVMTIagent: ... setting GarbageCollectionStart events done\n");
 995 
 996     /* MonitorContendedEnter events */
 997     display(0, "#### JVMTIagent: setting MonitorContendedEnter events ...\n");
 998 
 999     callbacks.MonitorContendedEnter = &MonitorContendedEnter;
1000 
1001     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1002             jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL)))
1003         return JNI_ERR;
1004     display(0, "#### JVMTIagent: ... setting MonitorContendedEnter events done\n");
1005 
1006     /* MonitorContendedEntered events */
1007     display(0, "#### JVMTIagent: setting MonitorContendedEntered events ...\n");
1008 
1009     callbacks.MonitorContendedEntered = &MonitorContendedEntered;
1010 
1011     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1012             jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL)))
1013         return JNI_ERR;
1014     display(0, "#### JVMTIagent: ... setting MonitorContendedEntered events done\n");
1015 
1016     /* MonitorWait events */
1017     display(0, "#### JVMTIagent: setting MonitorWait events ...\n");
1018 
1019     callbacks.MonitorWait = &MonitorWait;
1020 
1021     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1022             jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL)))
1023         return JNI_ERR;
1024     display(0, "#### JVMTIagent: ... setting MonitorWait events done\n");
1025 
1026     /* MonitorWaited events */
1027     display(0, "#### JVMTIagent: setting MonitorWaited events ...\n");
1028 
1029     callbacks.MonitorWaited = &MonitorWaited;
1030 
1031     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1032             jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL)))
1033         return JNI_ERR;
1034     display(0, "#### JVMTIagent: ... setting MonitorWaited events done\n");
1035 
1036     /* NativeMethodBind events */
1037     display(0, "#### JVMTIagent: setting NativeMethodBind events ...\n");
1038 
1039     callbacks.NativeMethodBind = &NativeMethodBind;
1040 
1041     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1042             jvmti, JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)))
1043         return JNI_ERR;
1044     display(0, "#### JVMTIagent: ... setting NativeMethodBind events done\n");
1045 
1046     /* ObjectFree events */
1047     display(0, "#### JVMTIagent: setting ObjectFree events ...\n");
1048 
1049     callbacks.ObjectFree = &ObjectFree;
1050 
1051     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1052             jvmti, JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)))
1053         return JNI_ERR;
1054     display(0, "#### JVMTIagent: ... setting ObjectFree events done\n");
1055 
1056     /* ThreadEnd events */
1057     display(0, "#### JVMTIagent: setting ThreadEnd events ...\n");
1058 
1059     callbacks.ThreadEnd = &ThreadEnd;
1060 
1061     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1062             jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL)))
1063         return JNI_ERR;
1064     display(0, "#### JVMTIagent: ... setting ThreadEnd events done\n");
1065 
1066     /* ThreadStart events */
1067     display(0, "#### JVMTIagent: setting ThreadStart events ...\n");
1068 
1069     callbacks.ThreadStart = &ThreadStart;
1070 
1071     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1072             jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL)))
1073         return JNI_ERR;
1074     display(0, "#### JVMTIagent: ... setting ThreadStart events done\n");
1075 
1076     /* VMDeath events */
1077     display(0, "#### JVMTIagent: setting VMDeath events ...\n");
1078 
1079     callbacks.VMDeath = &VMDeath;
1080 
1081     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1082             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
1083         return JNI_ERR;
1084     display(0, "#### JVMTIagent: ... setting VMDeath events done\n");
1085 
1086     /* VMInit events */
1087     display(0, "#### JVMTIagent: setting VMInit events ...\n");
1088 
1089     callbacks.VMInit = &VMInit;
1090 
1091     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1092             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL)))
1093         return JNI_ERR;
1094     display(0, "#### JVMTIagent: ... setting VMInit events done\n");
1095 
1096     /* VMStart events */
1097     display(0, "#### JVMTIagent: setting VMStart events ...\n");
1098 
1099     callbacks.VMStart = &VMStart;
1100 
1101     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1102             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
1103         return JNI_ERR;
1104     display(0, "#### JVMTIagent: ... setting VMStart events done\n");
1105 
1106     /* VMObjectAlloc events */
1107     display(0, "#### JVMTIagent: setting VMObjectAlloc events ...\n");
1108 
1109     callbacks.VMObjectAlloc = &VMObjectAlloc;
1110 
1111     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
1112             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL)))
1113         return JNI_ERR;
1114     display(0, "#### JVMTIagent: ... setting VMObjectAlloc events done\n");
1115 
1116     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks,
1117             jvmti, &callbacks, sizeof(callbacks))))
1118         return JNI_ERR;
1119 
1120     return 0;
1121 }
1122 
1123 static void clearJavaException(JNIEnv* jni_env) {
1124     if (NSK_CPP_STUB1(ExceptionOccurred, jni_env)) {
1125 
1126         NSK_CPP_STUB1(ExceptionDescribe, jni_env);
1127         NSK_CPP_STUB1(ExceptionClear, jni_env);
1128 
1129         NSK_CPP_STUB2(FatalError, jni_env,
1130             "JVMTIagent: exception occurred in java code, aborting\n");
1131     }
1132 }
1133 
1134 static int get_tok(char **src, char *buf, int buflen, char sep) {
1135     int i;
1136     char *p = *src;
1137     for (i = 0; i < buflen; i++) {
1138         if (p[i] == 0 || p[i] == sep) {
1139             buf[i] = 0;
1140             if (p[i] == sep) {
1141                 i++;
1142             }
1143             *src += i;
1144             return i;
1145         }
1146         buf[i] = p[i];
1147     }
1148     /* overflow */
1149     return 0;
1150 }
1151 
1152 static void doSetup(char *str) {
1153     if (str == 0)
1154         str = (char*) "";
1155 
1156     if ((strcmp(str, "help")) == 0) {
1157         printf("#### JVMTIagent usage: -agentlib:JVMTIagent[=[help]|[=[verbose]|[verbose2],[stress0|stress1|stress2|stress3]]]\n");
1158         printf("####      where: help\tprint this message\n");
1159         printf("####             verbose\tturn verbose mode on\n");
1160         printf("####             verbose2\tturn extended verbose mode on (including reporting JVMTI events)\n");
1161         printf("####             stress0, or empty value\tturn stress level 0 on (default mode):\n");
1162         printf("####                   enable event generation except ExceptionCatch, MethodEntry/Exit, SingleStep\n");
1163         printf("####             stress1\tturn stress level 1 on:\n");
1164         printf("####                   enable generation of ExceptionCatch events\n");
1165         printf("####             stress2\tturn stress level 2 on:\n");
1166         printf("####                   enable generation of ExceptionCatch,\n");
1167         printf("####                                        MethodEntry/Exit events\n");
1168         printf("####             stress3\tturn stress level 3 on:\n");
1169         printf("####                   enable generation of ExceptionCatch,\n");
1170         printf("####                                        MethodEntry/Exit,\n");
1171         printf("####                                        SingleStep events\n");
1172         exit(1);
1173     }
1174 
1175     while (*str) {
1176         char buf[1000];
1177 
1178         if (!get_tok(&str, buf, sizeof(buf), ',')) {
1179             printf("ERROR: JVMTIagent: bad option: \"%s\"!\n", str);
1180             exit(1);
1181         }
1182         if ((strcmp(buf, "verbose")) == 0) {
1183             printf("#### JVMTIagent: turned verbose mode on ####\n");
1184             debug_mode = 1;
1185         }
1186         if ((strcmp(buf, "verbose2")) == 0) {
1187             printf("#### JVMTIagent: turned extended verbose mode on ####\n");
1188             debug_mode = 2;
1189         }
1190         if ((strcmp(buf, "stress0")) == 0) {
1191             if (debug_mode > 0)
1192                 printf("#### JVMTIagent: turned stress level 0 on ####\n");
1193             stress_lev = 0;
1194         }
1195         if ((strcmp(buf, "stress1")) == 0) {
1196             if (debug_mode > 0)
1197                 printf("#### JVMTIagent: turned stress level 1 on ####\n");
1198             stress_lev = 1;
1199         }
1200         if ((strcmp(buf, "stress2")) == 0) {
1201             if (debug_mode > 0)
1202                 printf("#### JVMTIagent: turned stress level 2 on ####\n");
1203             stress_lev = 2;
1204         }
1205         if ((strcmp(buf, "stress3")) == 0) {
1206             if (debug_mode > 0)
1207                 printf("#### JVMTIagent: turned stress level 3 on ####\n");
1208             stress_lev = 3;
1209         }
1210     }
1211 }
1212 
1213 static void getVerdict(JNIEnv *jni_env, const char *evnt) {
1214     char error_msg[80];
1215 
1216     if (vm_death_occured == TRUE) {
1217         sprintf(error_msg, "JVMTIagent: getVerdict: %s event occured after VMDeath",
1218             evnt);
1219 
1220         if (jni_env==NULL) { /* some event callbacks have no pointer to jni */
1221             printf("ERROR: %s\n", error_msg);
1222             exit(97);
1223         }
1224         else
1225             NSK_CPP_STUB2(FatalError, jni_env, error_msg);
1226     }
1227 }
1228 
1229 static void display(int level, const char format[], ...) {
1230     va_list ar;
1231 
1232     if (debug_mode > level) {
1233         va_start(ar, format);
1234         vprintf(format, ar);
1235         va_end(ar);
1236     }
1237 }
1238 
1239 /* agent procedure */
1240 static void JNICALL
1241 agentProc(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg) {
1242 }
1243 
1244 JNIEXPORT jint JNICALL
1245 Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
1246     /* create JVMTI environment */
1247     if (!NSK_VERIFY((jvmti =
1248             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
1249         return JNI_ERR;
1250 
1251     doSetup(options);
1252 
1253     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor,
1254             jvmti, "_event_lock", &eventLock)))
1255         return JNI_ERR;
1256 
1257     if (enableEventsCaps() == 0 && addStressEvents() == 0) {
1258         display(0, "#### JVMTIagent: all events were successfully enabled and capabilities/events callbacks set ####\n\n");
1259     } else {
1260         printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",
1261             __FILE__,__LINE__);
1262         return JNI_ERR;
1263     }
1264 
1265     /* register agent proc and arg */
1266     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
1267         return JNI_ERR;
1268 
1269     return JNI_OK;
1270 }
1271 
1272 }