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