--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/JVMTIagent.c Mon Apr 30 18:10:24 2018 -0700
@@ -0,0 +1,1276 @@
+/*
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *
+ * JVMTI agent used for run every test from the testbase in a special
+ * debug mode. This mode is intended to be part of serviceability
+ * reliability testing.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <jvmti.h>
+
+#include "nsk_tools.h"
+#include "jni_tools.h"
+#include "JVMTITools.h"
+#include "jvmti_tools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static jvmtiEnv *jvmti = NULL; /* JVMTI env */
+static jvmtiEventCallbacks callbacks;
+static jrawMonitorID eventLock; /* raw monitor used for exclusive ownership of HotSwap function */
+
+static volatile int debug_mode = 0; /* 0 - verbose mode off;
+ 1 - verbose mode on;
+ 2 - verbose mode on including all JVMTI events reporting,
+ produces a huge number of messages */
+
+/* stress level */
+static volatile int stress_lev = 0; /* 0 - default mode: generation of all events except
+ ExceptionCatch,
+ MethodEntry/Exit, SingleStep;
+ 1 - generation of all events except
+ MethodEntry/Exit,
+ SingleStep;
+ 2 - generation of all events except
+ SingleStep;
+ 3 - generation of all events, including
+ ExceptionCatch,
+ MethodEntry/Exit,
+ SingleStep
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+/**** the following is used for "postVM_DEATH" events watching ****/
+static volatile int vm_death_occured = FALSE;
+/************************************************/
+
+/**** the following is used for HotSwap mode ****/
+
+/* HotSwap modes:
+ HOTSWAP_OFF - default mode: HotSwap off;
+ HOTSWAP_EVERY_METHOD_ENTRY - HotSwap tested class in every method entry event
+ of running test
+ HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS - HotSwap tested class in every
+ method entry event of every class
+ HOTSWAP_EVERY_SINGLE_STEP - HotSwap tested class in every single step event
+ of running test
+ HOTSWAP_EVERY_EXCEPTION - HotSwap tested class in every exception event
+ of running test
+ HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS - HotSwap tested class in every
+ exception event of every class
+ */
+
+#define HOTSWAP_OFF 0
+#define HOTSWAP_EVERY_METHOD_ENTRY 2
+#define HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS 20
+#define HOTSWAP_EVERY_SINGLE_STEP 3
+#define HOTSWAP_EVERY_EXCEPTION 4
+#define HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS 40
+
+static int hotswap = HOTSWAP_OFF;
+
+typedef struct { /* test class info */
+ char *clazzsig; /* class signature */
+ jclass cls; /* a class to be redefined */
+ jint bCount; /* number of bytes defining the class */
+ jbyte *clsBytes; /* bytes defining the class */
+ struct class_info *next;
+} class_info;
+
+
+static const char *shortTestName = NULL; /* name of the test without package prefix */
+static jclass rasCls; /* reference to the auxiliary class RASagent used for HotSwap */
+static class_info *clsInfo = NULL, *clsInfoFst = NULL;
+
+static void lock(JNIEnv*);
+static void unlock(JNIEnv*);
+static jint allocClsInfo(JNIEnv*, char*, jclass);
+static void deallocClsInfo(JNIEnv*);
+static int findAndHotSwap(JNIEnv*, jclass);
+static int doHotSwap(JNIEnv*, jclass, jint, jbyte*);
+static void display(int, const char format[], ...);
+static void clearJavaException(JNIEnv*);
+static int enableEventsCaps();
+static int addStressEvents();
+static void getVerdict(JNIEnv*, const char *);
+/************************************************/
+
+/** callback functions **/
+void JNICALL
+Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr, jmethodID method,
+ jlocation loc) {
+
+ display(1, "#### JVMTIagent: Breakpoint occurred ####\n");
+
+ getVerdict(jni_env, "Breakpoint");
+}
+
+void JNICALL
+ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jclass class_beeing_redefined,
+ jobject loader, const char* name, jobject protection_domain,
+ jint class_data_len, const unsigned char* class_data,
+ jint *new_class_data_len, unsigned char** new_class_data) {
+
+ display(1, "#### JVMTIagent: ClassFileLoadHook occurred ####\n");
+
+ getVerdict(jni_env, "ClassFileLoadHook");
+}
+
+void JNICALL
+ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread, jclass klass) {
+ char *cls_sig;
+ jint clsByteCount;
+
+ display((hotswap != HOTSWAP_OFF)?0:1,
+ "#### JVMTIagent: ClassLoad occurred ####\n");
+
+ getVerdict(jni_env, "ClassLoad");
+
+ if (hotswap != HOTSWAP_OFF) {
+ /* enter into a raw monitor for exclusive work with redefined class */
+ lock(jni_env);
+ display(0, "#### JVMTIagent: ClassLoad: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature,
+ jvmti_env, klass, &cls_sig, /*&generic*/NULL)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get class signature\n");
+ else {
+ if (shortTestName != NULL) {
+ if (strstr((const char*) cls_sig, shortTestName) != NULL) {
+ display(0, "#### JVMTIagent: found test class matched with \"%s\"\n\
+<JVMTIagent>\tsignature=%s\n",
+ shortTestName, cls_sig);
+ clsByteCount = allocClsInfo(jni_env, cls_sig, klass);
+ display(0, "#### JVMTIagent: %d bytes defining the class have been successfully loaded\n",
+ clsByteCount);
+ }
+ }
+ }
+
+ /* exit from the raw monitor */
+ unlock(jni_env);
+ display(0, "#### JVMTIagent: ClassLoad: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");
+ }
+}
+
+void JNICALL
+ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jclass cls) {
+
+ display(1, "#### JVMTIagent: ClassPrepare occurred ####\n");
+
+ getVerdict(jni_env, "ClassPrepare");
+}
+
+void JNICALL
+CompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size,
+ const void* code_addr, jint map_length,
+ const jvmtiAddrLocationMap* map, const void* compile_info) {
+
+ display(1, "#### JVMTIagent: CompiledMethodLoad occurred ####\n");
+
+ getVerdict(NULL, "CompiledMethodLoad");
+}
+
+void JNICALL
+CompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method,
+ const void* code_addr) {
+
+ display(1, "#### JVMTIagent: CompiledMethodUnload occurred ####\n");
+
+ getVerdict(NULL, "CompiledMethodUnload");
+}
+
+void JNICALL
+DataDumpRequest(jvmtiEnv *jvmti_env) {
+
+ display(1, "#### JVMTIagent: DataDumpRequest occurred ####\n");
+
+ getVerdict(NULL, "DataDumpRequest");
+}
+
+void JNICALL
+DynamicCodeGenerated(jvmtiEnv *jvmti_env,
+ const char* name,
+ const void* address,
+ jint length) {
+
+ display(1, "#### JVMTIagent: DynamicCodeGenerated occurred ####\n");
+
+ getVerdict(NULL, "DynamicCodeGenerated");
+}
+
+void JNICALL
+Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,
+ jmethodID method, jlocation location, jobject exception,
+ jmethodID catch_method, jlocation catch_location) {
+ jclass decl_clazz;
+
+ display((hotswap == HOTSWAP_EVERY_EXCEPTION ||
+ hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS)?0:1,
+ "#### JVMTIagent: Exception occurred ####\n");
+
+ getVerdict(jni_env, "Exception");
+
+ if (hotswap == HOTSWAP_EVERY_EXCEPTION ||
+ hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
+ jvmti_env, method, &decl_clazz)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get method declaring class\n");
+
+ if (findAndHotSwap(jni_env, decl_clazz) != 0)
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to hotswap class\n");
+ }
+}
+
+void JNICALL
+FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jmethodID method,
+ jlocation location, jclass field_klass, jobject obj, jfieldID field) {
+
+ display(1, "#### JVMTIagent: FieldAccess occurred ####\n");
+
+ getVerdict(jni_env, "FieldAccess");
+}
+
+void JNICALL
+FieldModification(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jmethodID method, jlocation location,
+ jclass field_klass, jobject obj,
+ jfieldID field, char sig, jvalue new_value) {
+
+ display(1, "#### JVMTIagent: FieldModification occurred ####\n");
+
+ getVerdict(jni_env, "FieldModification");
+}
+
+void JNICALL
+FramePop(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jmethodID method, jboolean wasPopedByException) {
+
+ display(1, "#### JVMTIagent: FramePop occurred ####\n");
+
+ getVerdict(jni_env, "FramePop");
+}
+
+void JNICALL
+GarbageCollectionFinish(jvmtiEnv *jvmti_env) {
+
+ display(1, "#### JVMTIagent: GarbageCollectionFinish occurred ####\n");
+
+ getVerdict(NULL, "GarbageCollectionFinish");
+}
+
+void JNICALL
+GarbageCollectionStart(jvmtiEnv *jvmti_env) {
+
+ display(1, "#### JVMTIagent: GarbageCollectionStart occurred ####\n");
+
+ getVerdict(NULL, "GarbageCollectionStart");
+}
+
+void JNICALL
+MonitorContendedEnter(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,
+ jobject obj) {
+
+ display(1, "#### JVMTIagent: MonitorContendedEnter occurred ####\n");
+
+ getVerdict(jni_env, "MonitorContendedEnter");
+}
+
+void JNICALL
+MonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,
+ jobject obj) {
+
+ display(1, "#### JVMTIagent: MonitorContendedEntered occurred ####\n");
+
+ getVerdict(jni_env, "MonitorContendedEntered");
+}
+
+void JNICALL
+MonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr, jobject obj,
+ jlong tout) {
+
+ display(1, "#### JVMTIagent: MonitorWait occurred ####\n");
+
+ getVerdict(jni_env, "MonitorWait");
+}
+
+void JNICALL
+MonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env,
+ jthread thr, jobject obj, jboolean timed_out) {
+
+ display(1, "#### JVMTIagent: MonitorWaited occurred ####\n");
+
+ getVerdict(jni_env, "MonitorWaited");
+}
+
+void JNICALL
+NativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
+ jmethodID method, void *addr, void **new_addr) {
+
+ display(1, "#### JVMTIagent: NativeMethodBind occurred ####\n");
+
+ getVerdict(jni_env, "NativeMethodBind");
+}
+
+void JNICALL
+ObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
+
+ display(1, "#### JVMTIagent: ObjectFree occurred ####\n");
+
+ getVerdict(NULL, "ObjectFree");
+}
+
+void JNICALL
+ThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
+
+ display(1, "#### JVMTIagent: ThreadEnd occurred ####\n");
+
+ getVerdict(jni_env, "ThreadEnd");
+}
+
+void JNICALL
+ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
+
+ display(1, "#### JVMTIagent: ThreadStart occurred ####\n");
+
+ getVerdict(jni_env, "ThreadStart");
+}
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv *jni_env) {
+ vm_death_occured = TRUE;
+
+ display(0, "#### JVMTIagent: VMDeath occurred ####\n");
+
+ if (hotswap != HOTSWAP_OFF) {
+ deallocClsInfo(jni_env);
+ display(0, "#### JVMTIagent: allocated memory was successfully freed ####\n");
+ }
+}
+
+void JNICALL
+VMInit(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr) {
+
+ display(0, "#### JVMTIagent: VMInit occurred ####\n");
+
+ getVerdict(jni_env, "VMInit");
+}
+
+void JNICALL
+VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+
+ display(0, "#### JVMTIagent: VMStart occurred ####\n");
+
+ getVerdict(jni_env, "VMStart");
+}
+
+JNIEXPORT void JNICALL
+VMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
+ jobject object, jclass object_klass, jlong size) {
+
+ display(1, "#### JVMTIagent: VMObjectAlloc occurred ####\n");
+
+ getVerdict(jni_env, "VMObjectAlloc");
+}
+
+void JNICALL
+SingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
+ jmethodID method, jlocation location) {
+ jclass decl_clazz;
+
+ display((hotswap == HOTSWAP_EVERY_SINGLE_STEP)?0:1,
+ "#### JVMTIagent: SingleStep occurred ####\n");
+
+ getVerdict(jni_env, "SingleStep");
+
+ if (hotswap == HOTSWAP_EVERY_SINGLE_STEP) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
+ jvmti_env, method, &decl_clazz)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get method declaring class\n");
+
+ if (findAndHotSwap(jni_env, decl_clazz) != 0)
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to hotswap class\n");
+ }
+}
+
+void JNICALL
+MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jmethodID method) {
+ jclass decl_clazz;
+
+ display((hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||
+ hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS)?0:1,
+ "#### JVMTIagent: MethodEntry occurred ####\n");
+
+ getVerdict(jni_env, "MethodEntry");
+
+ if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||
+ hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
+ jvmti_env, method, &decl_clazz)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get method declaring class\n");
+
+ if (findAndHotSwap(jni_env, decl_clazz) != 0)
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to hotswap class\n");
+ }
+}
+
+void JNICALL
+MethodExit(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
+ jthread thr, jmethodID method,
+ jboolean was_poped_by_exc, jvalue return_value) {
+
+ display(1, "#### JVMTIagent: MethodExit occurred ####\n");
+
+ getVerdict(jni_env, "MethodExit");
+}
+
+void JNICALL
+ExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,
+ jmethodID method, jlocation location, jobject exception) {
+ jclass decl_clazz;
+
+ display((hotswap == HOTSWAP_EVERY_EXCEPTION ||
+ hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS)?0:1,
+ "#### JVMTIagent: ExceptionCatch occurred ####\n");
+
+ getVerdict(jni_env, "ExceptionCatch");
+
+ if (hotswap == HOTSWAP_EVERY_EXCEPTION ||
+ hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
+ jvmti_env, method, &decl_clazz)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get method declaring class\n");
+
+ if (findAndHotSwap(jni_env, decl_clazz) != 0)
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to hotswap class\n");
+ }
+}
+/************************/
+
+static void lock(JNIEnv *jni_env) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter,
+ jvmti, eventLock)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to enter a raw monitor\n");
+}
+
+static void unlock(JNIEnv *jni_env) {
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit,
+ jvmti, eventLock)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to exit a raw monitor\n");
+}
+
+JNIEXPORT jint JNICALL
+Java_nsk_share_RASagent_setHotSwapMode(JNIEnv *jni_env, jclass cls,
+ jboolean vrb, jint level, jstring shortName) {
+ jvmtiCapabilities capabil;
+ jmethodID mid = NULL;
+
+ if (jvmti == NULL) {
+ printf("ERROR(%s,%d): JVMTIagent was not properly loaded: JVMTI env = NULL\n",
+ __FILE__, __LINE__);
+ return 1;
+ }
+
+ /* get supported JVMTI capabilities */
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities,
+ jvmti, &capabil)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to get capabilities\n");
+ if (capabil.can_redefine_classes != 1) { /* ???????????? */
+ printf("ERROR: JVMTIagent: Class File Redefinition (HotSwap) is not implemented in this VM\n");
+ return 1;
+ }
+
+ if (vrb == JNI_TRUE && debug_mode == 0)
+ debug_mode = 1;
+
+ hotswap = level;
+ switch (hotswap) {
+ case HOTSWAP_OFF:
+ display(0, "#### JVMTIagent: hotswap mode off ####\n");
+ return 0;
+ case HOTSWAP_EVERY_METHOD_ENTRY:
+ stress_lev = 2;
+ display(0, "#### JVMTIagent: hotswapping class in every method entry event enabled ####\n\
+<JVMTIagent>\tHotSwap stress level: %d\n",
+ stress_lev);
+ break;
+ case HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS:
+ stress_lev = 2;
+ display(0, "#### JVMTIagent: hotswapping class in every method entry event for every class enabled ####\n\
+<JVMTIagent>\tHotSwap stress level: %d\n",
+ stress_lev);
+ break;
+ case HOTSWAP_EVERY_SINGLE_STEP:
+ stress_lev = 3;
+ display(0, "#### JVMTIagent: hotswapping class in every single step event enabled ####\n\
+<JVMTIagent>\tHotSwap stress level: %d\n",
+ stress_lev);
+ break;
+ case HOTSWAP_EVERY_EXCEPTION:
+ stress_lev = 4;
+ display(0, "#### JVMTIagent: hotswapping class in every exception event enabled ####\n\
+<JVMTIagent>\tHotSwap stress level: %d\n",
+ stress_lev);
+ break;
+ case HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS:
+ stress_lev = 40;
+ display(0, "#### JVMTIagent: hotswapping class in every exception event for every class enabled ####\n\
+<JVMTIagent>\tHotSwap stress level: %d\n",
+ stress_lev);
+ break;
+ default:
+ printf("ERROR(%s,%d): JVMTIagent: unknown value of HotSwap stress level: \"%d\"\n",
+ __FILE__,__LINE__,hotswap);
+ return 1;
+ }
+
+ if (!NSK_JNI_VERIFY(jni_env, (shortTestName = NSK_CPP_STUB3(GetStringUTFChars,
+ jni_env, shortName, NULL)) != NULL)) {
+ printf("ERROR: JVMTIagent: unable to get UTF-8 characters of the string\n");
+ return 1;
+ }
+ display(0, "#### JVMTIagent: short name of current test is \"%s\"\n",
+ shortTestName);
+
+ if (!NSK_JNI_VERIFY(jni_env, (rasCls = NSK_CPP_STUB2(NewGlobalRef,
+ jni_env, cls)) != NULL)) {
+ printf("ERROR JVMTIagent: unable to create a new global reference of the class \"RASagent\"\n");
+ return 1;
+ }
+
+ if (addStressEvents() != 0) {
+ printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",
+ __FILE__,__LINE__);
+ return 1;
+ }
+
+ return 0;
+}
+
+static jint allocClsInfo(JNIEnv *jni_env, char *cls_sig, jclass clazz) {
+ class_info *_clsInfo = NULL;
+ jmethodID mid = NULL;
+ jbyteArray classBytes;
+ jboolean isCopy;
+
+ if ((_clsInfo = (class_info*)
+ malloc(sizeof(class_info))) == NULL)
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: cannot allocate memory for class_info\n");
+
+ /* fill the structure class_info */
+ _clsInfo->clazzsig = cls_sig;
+
+ if (!NSK_JNI_VERIFY(jni_env, ((*_clsInfo).cls = NSK_CPP_STUB2(NewGlobalRef,
+ jni_env, clazz)) != NULL)) {
+ printf("ERROR: JVMTIagent: unable to create a new global reference of class \"%s\"\n",
+ _clsInfo->clazzsig);
+ free(_clsInfo);
+ deallocClsInfo(jni_env);
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: unable to create a new global reference of class\n");
+ }
+
+ if (!NSK_JNI_VERIFY(jni_env, (mid =
+ NSK_CPP_STUB4(GetStaticMethodID, jni_env, rasCls,
+ "loadFromClassFile", "(Ljava/lang/String;)[B")) != NULL))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: unable to get ID of the method \"loadFromClassFile\"\n");
+
+ classBytes = (jbyteArray) NSK_CPP_STUB4(CallStaticObjectMethod,
+ jni_env, rasCls, mid, NSK_CPP_STUB2(NewStringUTF, jni_env, cls_sig));
+
+ clearJavaException(jni_env);
+
+ (*_clsInfo).bCount = NSK_CPP_STUB2(GetArrayLength, jni_env, classBytes);
+
+ (*_clsInfo).clsBytes =
+ NSK_CPP_STUB3(GetByteArrayElements, jni_env, classBytes, &isCopy);
+
+ _clsInfo->next = NULL;
+
+ if (clsInfo != NULL) {
+ clsInfo->next = (struct class_info*) _clsInfo;
+ }
+ else {
+ clsInfoFst = _clsInfo;
+ }
+ clsInfo = _clsInfo;
+
+ return (*_clsInfo).bCount;
+}
+
+static void deallocClsInfo(JNIEnv *jni_env) {
+ class_info *clsInfoCurr = clsInfoFst;
+
+ NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni_env, rasCls));
+
+ while(clsInfoCurr != NULL) {
+ class_info *_clsInfo = clsInfoCurr;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
+ jvmti, (unsigned char*) clsInfoCurr->clazzsig)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: failed to deallocate memory for clazzsig\n");
+
+ NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni_env, clsInfoCurr->cls));
+
+ clsInfoCurr = (class_info*) clsInfoCurr->next;
+
+ free(_clsInfo);
+ }
+ /* fix for 4756585: indicate that stucture class_info is empty now */
+ clsInfoFst = NULL;
+}
+
+static int findAndHotSwap(JNIEnv *jni_env, jclass clazz) {
+ int ret_code = 0;
+ char *clazzsig = NULL;
+ class_info *clsInfoCurr = clsInfoFst;
+
+ display(1, "\n#### JVMTIagent: findAndHotSwap: obtaining class signature of class to be hotswap ...\n");
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature,
+ jvmti, clazz, &clazzsig, /*&generic*/NULL)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: findAndHotSwap: failed to get class signature\n");
+ else {
+ display(1, "#### JVMTIagent: findAndHotSwap: ... class signature obtained: \"%s\"\n",
+ clazzsig);
+
+ /* enter into a raw monitor for exclusive work with redefined class */
+ lock(jni_env);
+ display(0, "#### JVMTIagent: findAndHotSwap: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");
+
+ while(clsInfoCurr != NULL) {
+ if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS ||
+ hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {
+ display(1, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" during execution of class \"%s\" ...\n",
+ clsInfoCurr->clazzsig, clazzsig);
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
+ jvmti, (unsigned char*) clazzsig)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");
+
+ if (doHotSwap(jni_env, clsInfoCurr->cls,
+ clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {
+ ret_code = 1;
+ break;
+ }
+ }
+ else {
+ if (strcmp(clazzsig, clsInfoCurr->clazzsig) == 0) {
+ display(0, "\n#### JVMTIagent: findAndHotSwap: tested class found \"%s\" ...\n",
+ clazzsig);
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
+ jvmti, (unsigned char*) clazzsig)))
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");
+
+ display(0, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" ...\n",
+ clsInfoCurr->clazzsig);
+ if (doHotSwap(jni_env, clsInfoCurr->cls,
+ clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {
+ ret_code = 1;
+ break;
+ }
+ }
+ }
+
+ clsInfoCurr = (class_info*) clsInfoCurr->next;
+ }
+
+ /* exit raw monitor */
+ unlock(jni_env);
+ display(0, "#### JVMTIagent: findAndHotSwap: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");
+ }
+
+ return ret_code;
+}
+
+static int doHotSwap(JNIEnv *jni_env, jclass redefCls, jint bCount,
+ jbyte *classBytes) {
+ jvmtiClassDefinition classDef;
+
+ /* fill the structure jvmtiClassDefinition */
+ classDef.klass = redefCls;
+ classDef.class_byte_count = bCount;
+ classDef.class_bytes = (unsigned char*) classBytes;
+
+ display(0, "#### JVMTIagent: >>>>>>>> Invoke RedefineClasses():\n\
+<JVMTIagent>\tnew class byte count=%d\n",
+ classDef.class_byte_count);
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RedefineClasses,
+ jvmti, 1, &classDef)))
+ return 1;
+
+ display(0, "#### JVMTIagent: <<<<<<<< RedefineClasses() is successfully done ####\n");
+
+ return 0;
+}
+
+static int addStressEvents() {
+ static int stepEventSet = JNI_FALSE;
+ static int methodsEventSet = JNI_FALSE;
+ static int excCatchEventSet = JNI_FALSE;
+
+ if (stress_lev >= 3) {
+ /* SingleStep events */
+ if (stepEventSet == JNI_FALSE) { /* don't set the event twice */
+ display(0, "#### JVMTIagent: setting SingleStep events ...\n");
+
+ callbacks.SingleStep = &SingleStep;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, NULL)))
+ return JNI_ERR;
+
+ stepEventSet = JNI_TRUE;
+
+ display(0, "#### JVMTIagent: ... setting SingleStep events done\n");
+ }
+ }
+
+ if (stress_lev >= 2) {
+ /* MethodEntry/Exit events */
+ if (methodsEventSet == JNI_FALSE) { /* don't set the event twice */
+ display(0, "#### JVMTIagent: setting MethodEntry events ...\n");
+
+ callbacks.MethodEntry = &MethodEntry;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL)))
+ return JNI_ERR;
+
+ display(0, "#### JVMTIagent: ... setting MethodEntry events done\n");
+
+ /* MethodExit events */
+ display(0, "#### JVMTIagent: setting MethodExit events ...\n");
+
+ callbacks.MethodExit = &MethodExit;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL)))
+ return JNI_ERR;
+
+ display(0, "#### JVMTIagent: ... setting MethodExit events done\n");
+
+ methodsEventSet = JNI_TRUE;
+ }
+ }
+
+ if (stress_lev >= 1) {
+ /* ExceptionCatch events */
+ if (excCatchEventSet == JNI_FALSE) { /* don't set the event twice */
+ display(0, "#### JVMTIagent: setting ExceptionCatch events ...\n");
+
+ callbacks.ExceptionCatch = &ExceptionCatch;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION_CATCH, NULL)))
+ return JNI_ERR;
+
+ excCatchEventSet = JNI_TRUE;
+
+ display(0, "#### JVMTIagent: ... setting ExceptionCatch events done\n");
+ }
+ }
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks,
+ jvmti, &callbacks, sizeof(callbacks))))
+ return JNI_ERR;
+ else
+ return 0;
+}
+
+static int enableEventsCaps() {
+ jvmtiCapabilities caps;
+
+ memset(&caps, 0, sizeof(jvmtiCapabilities));
+
+ /* add all capabilities */
+ caps.can_redefine_classes = 1;
+ caps.can_generate_breakpoint_events = 1;
+ caps.can_generate_all_class_hook_events = 1;
+ caps.can_generate_single_step_events = 1;
+ caps.can_generate_method_entry_events = 1;
+ caps.can_generate_method_exit_events = 1;
+ caps.can_generate_exception_events = 1;
+ caps.can_generate_compiled_method_load_events = 1;
+ caps.can_generate_field_access_events = 1;
+ caps.can_generate_field_modification_events = 1;
+ caps.can_generate_frame_pop_events = 1;
+ caps.can_generate_garbage_collection_events = 1;
+ caps.can_generate_monitor_events = 1;
+ caps.can_generate_native_method_bind_events = 1;
+ caps.can_generate_object_free_events = 1;
+ caps.can_generate_vm_object_alloc_events = 1;
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities,
+ jvmti, &caps)))
+ return JNI_ERR;
+
+ /* Breakpoint events */
+ display(0, "#### JVMTIagent: setting Breakpoint events ...\n");
+
+ callbacks.Breakpoint = &Breakpoint;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting Breakpoint events done\n");
+
+ /* ClassFileLoadHook events */
+ display(0, "#### JVMTIagent: setting ClassFileLoadHook events ...\n");
+
+ callbacks.ClassFileLoadHook = &ClassFileLoadHook;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ClassFileLoadHook events done\n");
+
+ /* ClassLoad events */
+ display(0, "#### JVMTIagent: setting ClassLoad events ...\n");
+
+ callbacks.ClassLoad = &ClassLoad;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ClassLoad events done\n");
+
+ /* ClassPrepare events */
+ display(0, "#### JVMTIagent: setting ClassPrepare events ...\n");
+
+ callbacks.ClassPrepare = &ClassPrepare;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ClassPrepare events done\n");
+
+ /* CompiledMethodLoad events */
+ display(0, "#### JVMTIagent: setting CompiledMethodLoad events ...\n");
+
+ callbacks.CompiledMethodLoad = &CompiledMethodLoad;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting CompiledMethodLoad events done\n");
+
+ /* CompiledMethodUnload events */
+ display(0, "#### JVMTIagent: setting CompiledMethodUnload events ...\n");
+
+ callbacks.CompiledMethodUnload = &CompiledMethodUnload;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting CompiledMethodUnload events done\n");
+
+ /* DataDumpRequest events */
+ display(0, "#### JVMTIagent: setting DataDumpRequest events ...\n");
+
+ callbacks.DataDumpRequest = &DataDumpRequest;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting DataDumpRequest events done\n");
+
+ /* DynamicCodeGenerated events */
+ display(0, "#### JVMTIagent: setting DynamicCodeGenerated events ...\n");
+
+ callbacks.DynamicCodeGenerated = &DynamicCodeGenerated;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting DynamicCodeGenerated events done\n");
+
+ /* Exception events */
+ display(0, "#### JVMTIagent: setting Exception events ...\n");
+
+ callbacks.Exception = &Exception;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting Exception events done\n");
+
+ /* FieldAccess events */
+ display(0, "#### JVMTIagent: setting FieldAccess events ...\n");
+
+ callbacks.FieldAccess = &FieldAccess;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIELD_ACCESS, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting FieldAccess events done\n");
+
+ /* FieldModification events */
+ display(0, "#### JVMTIagent: setting FieldModification events ...\n");
+
+ callbacks.FieldModification = &FieldModification;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIELD_MODIFICATION, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting FieldModification events done\n");
+
+ /* FramePop events */
+ display(0, "#### JVMTIagent: setting FramePop events ...\n");
+
+ callbacks.FramePop = &FramePop;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting FramePop events done\n");
+
+ /* GarbageCollectionFinish events */
+ display(0, "#### JVMTIagent: setting GarbageCollectionFinish events ...\n");
+
+ callbacks.GarbageCollectionFinish = &GarbageCollectionFinish;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting GarbageCollectionFinish events done\n");
+
+ /* GarbageCollectionStart events */
+ display(0, "#### JVMTIagent: setting GarbageCollectionStart events ...\n");
+
+ callbacks.GarbageCollectionStart = &GarbageCollectionStart;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting GarbageCollectionStart events done\n");
+
+ /* MonitorContendedEnter events */
+ display(0, "#### JVMTIagent: setting MonitorContendedEnter events ...\n");
+
+ callbacks.MonitorContendedEnter = &MonitorContendedEnter;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting MonitorContendedEnter events done\n");
+
+ /* MonitorContendedEntered events */
+ display(0, "#### JVMTIagent: setting MonitorContendedEntered events ...\n");
+
+ callbacks.MonitorContendedEntered = &MonitorContendedEntered;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting MonitorContendedEntered events done\n");
+
+ /* MonitorWait events */
+ display(0, "#### JVMTIagent: setting MonitorWait events ...\n");
+
+ callbacks.MonitorWait = &MonitorWait;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting MonitorWait events done\n");
+
+ /* MonitorWaited events */
+ display(0, "#### JVMTIagent: setting MonitorWaited events ...\n");
+
+ callbacks.MonitorWaited = &MonitorWaited;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting MonitorWaited events done\n");
+
+ /* NativeMethodBind events */
+ display(0, "#### JVMTIagent: setting NativeMethodBind events ...\n");
+
+ callbacks.NativeMethodBind = &NativeMethodBind;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting NativeMethodBind events done\n");
+
+ /* ObjectFree events */
+ display(0, "#### JVMTIagent: setting ObjectFree events ...\n");
+
+ callbacks.ObjectFree = &ObjectFree;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ObjectFree events done\n");
+
+ /* ThreadEnd events */
+ display(0, "#### JVMTIagent: setting ThreadEnd events ...\n");
+
+ callbacks.ThreadEnd = &ThreadEnd;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ThreadEnd events done\n");
+
+ /* ThreadStart events */
+ display(0, "#### JVMTIagent: setting ThreadStart events ...\n");
+
+ callbacks.ThreadStart = &ThreadStart;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting ThreadStart events done\n");
+
+ /* VMDeath events */
+ display(0, "#### JVMTIagent: setting VMDeath events ...\n");
+
+ callbacks.VMDeath = &VMDeath;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting VMDeath events done\n");
+
+ /* VMInit events */
+ display(0, "#### JVMTIagent: setting VMInit events ...\n");
+
+ callbacks.VMInit = &VMInit;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting VMInit events done\n");
+
+ /* VMStart events */
+ display(0, "#### JVMTIagent: setting VMStart events ...\n");
+
+ callbacks.VMStart = &VMStart;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting VMStart events done\n");
+
+ /* VMObjectAlloc events */
+ display(0, "#### JVMTIagent: setting VMObjectAlloc events ...\n");
+
+ callbacks.VMObjectAlloc = &VMObjectAlloc;
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
+ jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL)))
+ return JNI_ERR;
+ display(0, "#### JVMTIagent: ... setting VMObjectAlloc events done\n");
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks,
+ jvmti, &callbacks, sizeof(callbacks))))
+ return JNI_ERR;
+
+ return 0;
+}
+
+static void clearJavaException(JNIEnv* jni_env) {
+ if (NSK_CPP_STUB1(ExceptionOccurred, jni_env)) {
+
+ NSK_CPP_STUB1(ExceptionDescribe, jni_env);
+ NSK_CPP_STUB1(ExceptionClear, jni_env);
+
+ NSK_CPP_STUB2(FatalError, jni_env,
+ "JVMTIagent: exception occurred in java code, aborting\n");
+ }
+}
+
+static int get_tok(char **src, char *buf, int buflen, char sep) {
+ int i;
+ char *p = *src;
+ for (i = 0; i < buflen; i++) {
+ if (p[i] == 0 || p[i] == sep) {
+ buf[i] = 0;
+ if (p[i] == sep) {
+ i++;
+ }
+ *src += i;
+ return i;
+ }
+ buf[i] = p[i];
+ }
+ /* overflow */
+ return 0;
+}
+
+static void doSetup(char *str) {
+ if (str == 0)
+ str = "";
+
+ if ((strcmp(str, "help")) == 0) {
+ printf("#### JVMTIagent usage: -agentlib:JVMTIagent[=[help]|[=[verbose]|[verbose2],[stress0|stress1|stress2|stress3]]]\n");
+ printf("#### where: help\tprint this message\n");
+ printf("#### verbose\tturn verbose mode on\n");
+ printf("#### verbose2\tturn extended verbose mode on (including reporting JVMTI events)\n");
+ printf("#### stress0, or empty value\tturn stress level 0 on (default mode):\n");
+ printf("#### enable event generation except ExceptionCatch, MethodEntry/Exit, SingleStep\n");
+ printf("#### stress1\tturn stress level 1 on:\n");
+ printf("#### enable generation of ExceptionCatch events\n");
+ printf("#### stress2\tturn stress level 2 on:\n");
+ printf("#### enable generation of ExceptionCatch,\n");
+ printf("#### MethodEntry/Exit events\n");
+ printf("#### stress3\tturn stress level 3 on:\n");
+ printf("#### enable generation of ExceptionCatch,\n");
+ printf("#### MethodEntry/Exit,\n");
+ printf("#### SingleStep events\n");
+ exit(1);
+ }
+
+ while (*str) {
+ char buf[1000];
+
+ if (!get_tok(&str, buf, sizeof(buf), ',')) {
+ printf("ERROR: JVMTIagent: bad option: \"%s\"!\n", str);
+ exit(1);
+ }
+ if ((strcmp(buf, "verbose")) == 0) {
+ printf("#### JVMTIagent: turned verbose mode on ####\n");
+ debug_mode = 1;
+ }
+ if ((strcmp(buf, "verbose2")) == 0) {
+ printf("#### JVMTIagent: turned extended verbose mode on ####\n");
+ debug_mode = 2;
+ }
+ if ((strcmp(buf, "stress0")) == 0) {
+ if (debug_mode > 0)
+ printf("#### JVMTIagent: turned stress level 0 on ####\n");
+ stress_lev = 0;
+ }
+ if ((strcmp(buf, "stress1")) == 0) {
+ if (debug_mode > 0)
+ printf("#### JVMTIagent: turned stress level 1 on ####\n");
+ stress_lev = 1;
+ }
+ if ((strcmp(buf, "stress2")) == 0) {
+ if (debug_mode > 0)
+ printf("#### JVMTIagent: turned stress level 2 on ####\n");
+ stress_lev = 2;
+ }
+ if ((strcmp(buf, "stress3")) == 0) {
+ if (debug_mode > 0)
+ printf("#### JVMTIagent: turned stress level 3 on ####\n");
+ stress_lev = 3;
+ }
+ }
+}
+
+static void getVerdict(JNIEnv *jni_env, const char *evnt) {
+ char error_msg[80];
+
+ if (vm_death_occured == TRUE) {
+ sprintf(error_msg, "JVMTIagent: getVerdict: %s event occured after VMDeath",
+ evnt);
+
+ if (jni_env==NULL) { /* some event callbacks have no pointer to jni */
+ printf("ERROR: %s\n", error_msg);
+ exit(97);
+ }
+ else
+ NSK_CPP_STUB2(FatalError, jni_env, error_msg);
+ }
+}
+
+static void display(int level, const char format[], ...) {
+ va_list ar;
+
+ if (debug_mode > level) {
+ va_start(ar, format);
+ vprintf(format, ar);
+ va_end(ar);
+ }
+}
+
+/* agent procedure */
+static void JNICALL
+agentProc(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg) {
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+ /* create JVMTI environment */
+ if (!NSK_VERIFY((jvmti =
+ nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
+ return JNI_ERR;
+
+ doSetup(options);
+
+ if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor,
+ jvmti, "_event_lock", &eventLock)))
+ return JNI_ERR;
+
+ if (enableEventsCaps() == 0 && addStressEvents() == 0) {
+ display(0, "#### JVMTIagent: all events were successfully enabled and capabilities/events callbacks set ####\n\n");
+ } else {
+ printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",
+ __FILE__,__LINE__);
+ return JNI_ERR;
+ }
+
+ /* register agent proc and arg */
+ if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
+ return JNI_ERR;
+
+ return JNI_OK;
+}
+
+#ifdef __cplusplus
+}
+#endif