Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/JVMTIagent.cpp
40948 views
/*1* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24*25* JVMTI agent used for run every test from the testbase in a special26* debug mode. This mode is intended to be part of serviceability27* reliability testing.28*/2930#include <stdio.h>31#include <stdlib.h>32#include <stdarg.h>33#include <string.h>34#include <jvmti.h>3536#include "nsk_tools.h"37#include "jni_tools.h"38#include "JVMTITools.h"39#include "jvmti_tools.h"4041extern "C" {4243static jvmtiEnv *jvmti = NULL; /* JVMTI env */44static jvmtiEventCallbacks callbacks;45static jrawMonitorID eventLock; /* raw monitor used for exclusive ownership of HotSwap function */4647static volatile int debug_mode = 0; /* 0 - verbose mode off;481 - verbose mode on;492 - verbose mode on including all JVMTI events reporting,50produces a huge number of messages */5152/* stress level */53static volatile int stress_lev = 0; /* 0 - default mode: generation of all events except54ExceptionCatch,55MethodEntry/Exit, SingleStep;561 - generation of all events except57MethodEntry/Exit,58SingleStep;592 - generation of all events except60SingleStep;613 - generation of all events, including62ExceptionCatch,63MethodEntry/Exit,64SingleStep65*/6667#define TRUE 168#define FALSE 06970/**** the following is used for "postVM_DEATH" events watching ****/71static volatile int vm_death_occured = FALSE;72/************************************************/7374/**** the following is used for HotSwap mode ****/7576/* HotSwap modes:77HOTSWAP_OFF - default mode: HotSwap off;78HOTSWAP_EVERY_METHOD_ENTRY - HotSwap tested class in every method entry event79of running test80HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS - HotSwap tested class in every81method entry event of every class82HOTSWAP_EVERY_SINGLE_STEP - HotSwap tested class in every single step event83of running test84HOTSWAP_EVERY_EXCEPTION - HotSwap tested class in every exception event85of running test86HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS - HotSwap tested class in every87exception event of every class88*/8990#define HOTSWAP_OFF 091#define HOTSWAP_EVERY_METHOD_ENTRY 292#define HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS 2093#define HOTSWAP_EVERY_SINGLE_STEP 394#define HOTSWAP_EVERY_EXCEPTION 495#define HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS 409697static int hotswap = HOTSWAP_OFF;9899typedef struct { /* test class info */100char *clazzsig; /* class signature */101jclass cls; /* a class to be redefined */102jint bCount; /* number of bytes defining the class */103jbyte *clsBytes; /* bytes defining the class */104struct class_info *next;105} class_info;106107108static const char *shortTestName = NULL; /* name of the test without package prefix */109static jclass rasCls; /* reference to the auxiliary class RASagent used for HotSwap */110static class_info *clsInfo = NULL, *clsInfoFst = NULL;111112static void lock(JNIEnv*);113static void unlock(JNIEnv*);114static jint allocClsInfo(JNIEnv*, char*, jclass);115static void deallocClsInfo(JNIEnv*);116static int findAndHotSwap(JNIEnv*, jclass);117static int doHotSwap(JNIEnv*, jclass, jint, jbyte*);118static void display(int, const char format[], ...);119static void clearJavaException(JNIEnv*);120static int enableEventsCaps();121static int addStressEvents();122static void getVerdict(JNIEnv*, const char *);123/************************************************/124125/** callback functions **/126void JNICALL127Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr, jmethodID method,128jlocation loc) {129130display(1, "#### JVMTIagent: Breakpoint occurred ####\n");131132getVerdict(jni_env, "Breakpoint");133}134135void JNICALL136ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env,137jclass class_beeing_redefined,138jobject loader, const char* name, jobject protection_domain,139jint class_data_len, const unsigned char* class_data,140jint *new_class_data_len, unsigned char** new_class_data) {141142display(1, "#### JVMTIagent: ClassFileLoadHook occurred ####\n");143144getVerdict(jni_env, "ClassFileLoadHook");145}146147void JNICALL148ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread, jclass klass) {149char *cls_sig;150jint clsByteCount;151152display((hotswap != HOTSWAP_OFF) ? 0 : 1,153"#### JVMTIagent: ClassLoad occurred ####\n");154155getVerdict(jni_env, "ClassLoad");156157if (hotswap != HOTSWAP_OFF) {158/* enter into a raw monitor for exclusive work with redefined class */159lock(jni_env);160display(0, "#### JVMTIagent: ClassLoad: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");161162if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &cls_sig, /*&generic*/NULL)))163jni_env->FatalError("JVMTIagent: failed to get class signature\n");164else {165if (shortTestName != NULL) {166if (strstr((const char*) cls_sig, shortTestName) != NULL) {167display(0,168"#### JVMTIagent: found test class matched with \"%s\"\n"169"<JVMTIagent>\tsignature=%s\n",170shortTestName, cls_sig);171clsByteCount = allocClsInfo(jni_env, cls_sig, klass);172display(0, "#### JVMTIagent: %d bytes defining the class have been successfully loaded\n",173clsByteCount);174}175}176}177178/* exit from the raw monitor */179unlock(jni_env);180display(0, "#### JVMTIagent: ClassLoad: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");181}182}183184void JNICALL185ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *jni_env,186jthread thr, jclass cls) {187188display(1, "#### JVMTIagent: ClassPrepare occurred ####\n");189190getVerdict(jni_env, "ClassPrepare");191}192193void JNICALL194CompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size,195const void* code_addr, jint map_length,196const jvmtiAddrLocationMap* map, const void* compile_info) {197198display(1, "#### JVMTIagent: CompiledMethodLoad occurred ####\n");199200getVerdict(NULL, "CompiledMethodLoad");201}202203void JNICALL204CompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method,205const void* code_addr) {206207display(1, "#### JVMTIagent: CompiledMethodUnload occurred ####\n");208209getVerdict(NULL, "CompiledMethodUnload");210}211212void JNICALL213DataDumpRequest(jvmtiEnv *jvmti_env) {214215display(1, "#### JVMTIagent: DataDumpRequest occurred ####\n");216217getVerdict(NULL, "DataDumpRequest");218}219220void JNICALL221DynamicCodeGenerated(jvmtiEnv *jvmti_env,222const char* name,223const void* address,224jint length) {225226display(1, "#### JVMTIagent: DynamicCodeGenerated occurred ####\n");227228getVerdict(NULL, "DynamicCodeGenerated");229}230231void JNICALL232Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,233jmethodID method, jlocation location, jobject exception,234jmethodID catch_method, jlocation catch_location) {235jclass decl_clazz;236237display((hotswap == HOTSWAP_EVERY_EXCEPTION ||238hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) ? 0 : 1,239"#### JVMTIagent: Exception occurred ####\n");240241getVerdict(jni_env, "Exception");242243if (hotswap == HOTSWAP_EVERY_EXCEPTION ||244hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {245if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &decl_clazz)))246jni_env->FatalError("JVMTIagent: failed to get method declaring class\n");247248if (findAndHotSwap(jni_env, decl_clazz) != 0)249jni_env->FatalError("JVMTIagent: failed to hotswap class\n");250}251}252253void JNICALL254FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *jni_env,255jthread thr, jmethodID method,256jlocation location, jclass field_klass, jobject obj, jfieldID field) {257258display(1, "#### JVMTIagent: FieldAccess occurred ####\n");259260getVerdict(jni_env, "FieldAccess");261}262263void JNICALL264FieldModification(jvmtiEnv *jvmti_env, JNIEnv *jni_env,265jthread thr, jmethodID method, jlocation location,266jclass field_klass, jobject obj,267jfieldID field, char sig, jvalue new_value) {268269display(1, "#### JVMTIagent: FieldModification occurred ####\n");270271getVerdict(jni_env, "FieldModification");272}273274void JNICALL275FramePop(jvmtiEnv *jvmti_env, JNIEnv *jni_env,276jthread thr, jmethodID method, jboolean wasPopedByException) {277278display(1, "#### JVMTIagent: FramePop occurred ####\n");279280getVerdict(jni_env, "FramePop");281}282283void JNICALL284GarbageCollectionFinish(jvmtiEnv *jvmti_env) {285286display(1, "#### JVMTIagent: GarbageCollectionFinish occurred ####\n");287288getVerdict(NULL, "GarbageCollectionFinish");289}290291void JNICALL292GarbageCollectionStart(jvmtiEnv *jvmti_env) {293294display(1, "#### JVMTIagent: GarbageCollectionStart occurred ####\n");295296getVerdict(NULL, "GarbageCollectionStart");297}298299void JNICALL300MonitorContendedEnter(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,301jobject obj) {302303display(1, "#### JVMTIagent: MonitorContendedEnter occurred ####\n");304305getVerdict(jni_env, "MonitorContendedEnter");306}307308void JNICALL309MonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr,310jobject obj) {311312display(1, "#### JVMTIagent: MonitorContendedEntered occurred ####\n");313314getVerdict(jni_env, "MonitorContendedEntered");315}316317void JNICALL318MonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thr, jobject obj,319jlong tout) {320321display(1, "#### JVMTIagent: MonitorWait occurred ####\n");322323getVerdict(jni_env, "MonitorWait");324}325326void JNICALL327MonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env,328jthread thr, jobject obj, jboolean timed_out) {329330display(1, "#### JVMTIagent: MonitorWaited occurred ####\n");331332getVerdict(jni_env, "MonitorWaited");333}334335void JNICALL336NativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,337jmethodID method, void *addr, void **new_addr) {338339display(1, "#### JVMTIagent: NativeMethodBind occurred ####\n");340341getVerdict(jni_env, "NativeMethodBind");342}343344void JNICALL345ObjectFree(jvmtiEnv *jvmti_env, jlong tag) {346347display(1, "#### JVMTIagent: ObjectFree occurred ####\n");348349getVerdict(NULL, "ObjectFree");350}351352void JNICALL353ThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {354355display(1, "#### JVMTIagent: ThreadEnd occurred ####\n");356357getVerdict(jni_env, "ThreadEnd");358}359360void JNICALL361ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {362363display(1, "#### JVMTIagent: ThreadStart occurred ####\n");364365getVerdict(jni_env, "ThreadStart");366}367368void JNICALL369VMDeath(jvmtiEnv *jvmti_env, JNIEnv *jni_env) {370vm_death_occured = TRUE;371372display(0, "#### JVMTIagent: VMDeath occurred ####\n");373374if (hotswap != HOTSWAP_OFF) {375deallocClsInfo(jni_env);376display(0, "#### JVMTIagent: allocated memory was successfully freed ####\n");377}378}379380void JNICALL381VMInit(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr) {382383display(0, "#### JVMTIagent: VMInit occurred ####\n");384385getVerdict(jni_env, "VMInit");386}387388void JNICALL389VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {390391display(0, "#### JVMTIagent: VMStart occurred ####\n");392393getVerdict(jni_env, "VMStart");394}395396JNIEXPORT void JNICALL397VMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,398jobject object, jclass object_klass, jlong size) {399400display(1, "#### JVMTIagent: VMObjectAlloc occurred ####\n");401402getVerdict(jni_env, "VMObjectAlloc");403}404405void JNICALL406SingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,407jmethodID method, jlocation location) {408jclass decl_clazz;409410display((hotswap == HOTSWAP_EVERY_SINGLE_STEP) ? 0 : 1,411"#### JVMTIagent: SingleStep occurred ####\n");412413getVerdict(jni_env, "SingleStep");414415if (hotswap == HOTSWAP_EVERY_SINGLE_STEP) {416if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &decl_clazz)))417jni_env->FatalError("JVMTIagent: failed to get method declaring class\n");418419if (findAndHotSwap(jni_env, decl_clazz) != 0)420jni_env->FatalError("JVMTIagent: failed to hotswap class\n");421}422}423424void JNICALL425MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *jni_env,426jthread thr, jmethodID method) {427jclass decl_clazz;428429display((hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||430hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS) ? 0 : 1,431"#### JVMTIagent: MethodEntry occurred ####\n");432433getVerdict(jni_env, "MethodEntry");434435if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY ||436hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS) {437if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &decl_clazz)))438jni_env->FatalError("JVMTIagent: failed to get method declaring class\n");439440if (findAndHotSwap(jni_env, decl_clazz) != 0)441jni_env->FatalError("JVMTIagent: failed to hotswap class\n");442}443}444445void JNICALL446MethodExit(jvmtiEnv *jvmti_env, JNIEnv *jni_env,447jthread thr, jmethodID method,448jboolean was_poped_by_exc, jvalue return_value) {449450display(1, "#### JVMTIagent: MethodExit occurred ####\n");451452getVerdict(jni_env, "MethodExit");453}454455void JNICALL456ExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thr,457jmethodID method, jlocation location, jobject exception) {458jclass decl_clazz;459460display((hotswap == HOTSWAP_EVERY_EXCEPTION ||461hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) ? 0 : 1,462"#### JVMTIagent: ExceptionCatch occurred ####\n");463464getVerdict(jni_env, "ExceptionCatch");465466if (hotswap == HOTSWAP_EVERY_EXCEPTION ||467hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {468if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &decl_clazz)))469jni_env->FatalError("JVMTIagent: failed to get method declaring class\n");470471if (findAndHotSwap(jni_env, decl_clazz) != 0)472jni_env->FatalError("JVMTIagent: failed to hotswap class\n");473}474}475/************************/476477static void lock(JNIEnv *jni_env) {478if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(eventLock)))479jni_env->FatalError("JVMTIagent: failed to enter a raw monitor\n");480}481482static void unlock(JNIEnv *jni_env) {483if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(eventLock)))484jni_env->FatalError("JVMTIagent: failed to exit a raw monitor\n");485}486487JNIEXPORT jint JNICALL488Java_nsk_share_RASagent_setHotSwapMode(JNIEnv *jni_env, jclass cls,489jboolean vrb, jint level, jstring shortName) {490jvmtiCapabilities capabil;491jmethodID mid = NULL;492493if (jvmti == NULL) {494printf("ERROR(%s,%d): JVMTIagent was not properly loaded: JVMTI env = NULL\n",495__FILE__, __LINE__);496return 1;497}498499/* get supported JVMTI capabilities */500if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&capabil)))501jni_env->FatalError("JVMTIagent: failed to get capabilities\n");502if (capabil.can_redefine_classes != 1) { /* ???????????? */503printf("ERROR: JVMTIagent: Class File Redefinition (HotSwap) is not implemented in this VM\n");504return 1;505}506507if (vrb == JNI_TRUE && debug_mode == 0)508debug_mode = 1;509510hotswap = level;511switch (hotswap) {512case HOTSWAP_OFF:513display(0, "#### JVMTIagent: hotswap mode off ####\n");514return 0;515case HOTSWAP_EVERY_METHOD_ENTRY:516stress_lev = 2;517display(0,518"#### JVMTIagent: hotswapping class in every method entry event enabled ####\n"519"<JVMTIagent>\tHotSwap stress level: %d\n",520stress_lev);521break;522case HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS:523stress_lev = 2;524display(0,525"#### JVMTIagent: hotswapping class in every method entry event for every class enabled ####\n"526"<JVMTIagent>\tHotSwap stress level: %d\n",527stress_lev);528break;529case HOTSWAP_EVERY_SINGLE_STEP:530stress_lev = 3;531display(0,532"#### JVMTIagent: hotswapping class in every single step event enabled ####\n"533"<JVMTIagent>\tHotSwap stress level: %d\n",534stress_lev);535break;536case HOTSWAP_EVERY_EXCEPTION:537stress_lev = 4;538display(0,539"#### JVMTIagent: hotswapping class in every exception event enabled ####\n"540"<JVMTIagent>\tHotSwap stress level: %d\n",541stress_lev);542break;543case HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS:544stress_lev = 40;545display(0,546"#### JVMTIagent: hotswapping class in every exception event for every class enabled ####\n"547"<JVMTIagent>\tHotSwap stress level: %d\n",548stress_lev);549break;550default:551printf("ERROR(%s,%d): JVMTIagent: unknown value of HotSwap stress level: \"%d\"\n",552__FILE__,__LINE__,hotswap);553return 1;554}555556if (!NSK_JNI_VERIFY(jni_env, (shortTestName = jni_env->GetStringUTFChars(shortName, NULL)) != NULL)) {557printf("ERROR: JVMTIagent: unable to get UTF-8 characters of the string\n");558return 1;559}560display(0, "#### JVMTIagent: short name of current test is \"%s\"\n",561shortTestName);562563if (!NSK_JNI_VERIFY(jni_env, (rasCls = jni_env->NewGlobalRef(cls)) != NULL)) {564printf("ERROR JVMTIagent: unable to create a new global reference of the class \"RASagent\"\n");565return 1;566}567568if (addStressEvents() != 0) {569printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",570__FILE__,__LINE__);571return 1;572}573574return 0;575}576577static jint allocClsInfo(JNIEnv *jni_env, char *cls_sig, jclass clazz) {578class_info *_clsInfo = NULL;579jmethodID mid = NULL;580jbyteArray classBytes;581jboolean isCopy;582583_clsInfo = (class_info*) malloc(sizeof(class_info));584if (_clsInfo == NULL)585jni_env->FatalError("JVMTIagent: cannot allocate memory for class_info\n");586587/* fill the structure class_info */588_clsInfo->clazzsig = cls_sig;589590if (!NSK_JNI_VERIFY(jni_env, ((*_clsInfo).cls = jni_env->NewGlobalRef(clazz)) != NULL)) {591printf("ERROR: JVMTIagent: unable to create a new global reference of class \"%s\"\n",592_clsInfo->clazzsig);593free(_clsInfo);594deallocClsInfo(jni_env);595jni_env->FatalError("JVMTIagent: unable to create a new global reference of class\n");596}597598if (!NSK_JNI_VERIFY(jni_env, (mid =599jni_env->GetStaticMethodID(rasCls, "loadFromClassFile", "(Ljava/lang/String;)[B")) != NULL))600jni_env->FatalError("JVMTIagent: unable to get ID of the method \"loadFromClassFile\"\n");601602classBytes = (jbyteArray) jni_env->CallStaticObjectMethod(rasCls, mid, jni_env->NewStringUTF(cls_sig));603604clearJavaException(jni_env);605606(*_clsInfo).bCount = jni_env->GetArrayLength(classBytes);607608(*_clsInfo).clsBytes =609jni_env->GetByteArrayElements(classBytes, &isCopy);610611_clsInfo->next = NULL;612613if (clsInfo != NULL) {614clsInfo->next = (struct class_info*) _clsInfo;615}616else {617clsInfoFst = _clsInfo;618}619clsInfo = _clsInfo;620621return (*_clsInfo).bCount;622}623624static void deallocClsInfo(JNIEnv *jni_env) {625class_info *clsInfoCurr = clsInfoFst;626627NSK_TRACE(jni_env->DeleteGlobalRef(rasCls));628629while (clsInfoCurr != NULL) {630class_info *_clsInfo = clsInfoCurr;631632if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*) clsInfoCurr->clazzsig)))633jni_env->FatalError("JVMTIagent: failed to deallocate memory for clazzsig\n");634635NSK_TRACE(jni_env->DeleteGlobalRef(clsInfoCurr->cls));636637clsInfoCurr = (class_info*) clsInfoCurr->next;638639free(_clsInfo);640}641/* fix for 4756585: indicate that stucture class_info is empty now */642clsInfoFst = NULL;643}644645static int findAndHotSwap(JNIEnv *jni_env, jclass clazz) {646int ret_code = 0;647char *clazzsig = NULL;648class_info *clsInfoCurr = clsInfoFst;649650display(1, "\n#### JVMTIagent: findAndHotSwap: obtaining class signature of class to be hotswap ...\n");651if (!NSK_JVMTI_VERIFY(jvmti->GetClassSignature(clazz, &clazzsig, /*&generic*/NULL)))652jni_env->FatalError("JVMTIagent: findAndHotSwap: failed to get class signature\n");653else {654display(1, "#### JVMTIagent: findAndHotSwap: ... class signature obtained: \"%s\"\n",655clazzsig);656657/* enter into a raw monitor for exclusive work with redefined class */658lock(jni_env);659display(0, "#### JVMTIagent: findAndHotSwap: >>>>>>>> entered the raw monitor \"eventLock\" ####\n");660661while (clsInfoCurr != NULL) {662if (hotswap == HOTSWAP_EVERY_METHOD_ENTRY_FOR_EVERY_CLASS ||663hotswap == HOTSWAP_EVERY_EXCEPTION_FOR_EVERY_CLASS) {664display(1, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" during execution of class \"%s\" ...\n",665clsInfoCurr->clazzsig, clazzsig);666if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*) clazzsig)))667jni_env->FatalError("JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");668669if (doHotSwap(jni_env, clsInfoCurr->cls,670clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {671ret_code = 1;672break;673}674}675else {676if (strcmp(clazzsig, clsInfoCurr->clazzsig) == 0) {677display(0, "\n#### JVMTIagent: findAndHotSwap: tested class found \"%s\" ...\n",678clazzsig);679680if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*) clazzsig)))681jni_env->FatalError("JVMTIagent: findAndHotSwap: failed to deallocate memory for clazzsig\n");682683display(0, "\n#### JVMTIagent: findAndHotSwap: going to hotswap tested class \"%s\" ...\n",684clsInfoCurr->clazzsig);685if (doHotSwap(jni_env, clsInfoCurr->cls,686clsInfoCurr->bCount, clsInfoCurr->clsBytes) != 0) {687ret_code = 1;688break;689}690}691}692693clsInfoCurr = (class_info*) clsInfoCurr->next;694}695696/* exit raw monitor */697unlock(jni_env);698display(0, "#### JVMTIagent: findAndHotSwap: <<<<<<<< exited from the raw monitor \"eventLock\" ####\n\n");699}700701return ret_code;702}703704static int doHotSwap(JNIEnv *jni_env, jclass redefCls, jint bCount,705jbyte *classBytes) {706jvmtiClassDefinition classDef;707708/* fill the structure jvmtiClassDefinition */709classDef.klass = redefCls;710classDef.class_byte_count = bCount;711classDef.class_bytes = (unsigned char*) classBytes;712713display(0,714"#### JVMTIagent: >>>>>>>> Invoke RedefineClasses():\n"715"<JVMTIagent>\tnew class byte count=%d\n",716classDef.class_byte_count);717if (!NSK_JVMTI_VERIFY(jvmti->RedefineClasses(1, &classDef)))718return 1;719720display(0, "#### JVMTIagent: <<<<<<<< RedefineClasses() is successfully done ####\n");721722return 0;723}724725static int addStressEvents() {726static int stepEventSet = JNI_FALSE;727static int methodsEventSet = JNI_FALSE;728static int excCatchEventSet = JNI_FALSE;729730if (stress_lev >= 3) {731/* SingleStep events */732if (stepEventSet == JNI_FALSE) { /* don't set the event twice */733display(0, "#### JVMTIagent: setting SingleStep events ...\n");734735callbacks.SingleStep = &SingleStep;736737if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, NULL)))738return JNI_ERR;739740stepEventSet = JNI_TRUE;741742display(0, "#### JVMTIagent: ... setting SingleStep events done\n");743}744}745746if (stress_lev >= 2) {747/* MethodEntry/Exit events */748if (methodsEventSet == JNI_FALSE) { /* don't set the event twice */749display(0, "#### JVMTIagent: setting MethodEntry events ...\n");750751callbacks.MethodEntry = &MethodEntry;752753if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL)))754return JNI_ERR;755756display(0, "#### JVMTIagent: ... setting MethodEntry events done\n");757758/* MethodExit events */759display(0, "#### JVMTIagent: setting MethodExit events ...\n");760761callbacks.MethodExit = &MethodExit;762763if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, NULL)))764return JNI_ERR;765766display(0, "#### JVMTIagent: ... setting MethodExit events done\n");767768methodsEventSet = JNI_TRUE;769}770}771772if (stress_lev >= 1) {773/* ExceptionCatch events */774if (excCatchEventSet == JNI_FALSE) { /* don't set the event twice */775display(0, "#### JVMTIagent: setting ExceptionCatch events ...\n");776777callbacks.ExceptionCatch = &ExceptionCatch;778779if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION_CATCH, NULL)))780return JNI_ERR;781782excCatchEventSet = JNI_TRUE;783784display(0, "#### JVMTIagent: ... setting ExceptionCatch events done\n");785}786}787788if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))789return JNI_ERR;790else791return 0;792}793794static int enableEventsCaps() {795jvmtiCapabilities caps;796797memset(&caps, 0, sizeof(jvmtiCapabilities));798799/* add all capabilities */800caps.can_redefine_classes = 1;801caps.can_generate_breakpoint_events = 1;802caps.can_generate_all_class_hook_events = 1;803caps.can_generate_single_step_events = 1;804caps.can_generate_method_entry_events = 1;805caps.can_generate_method_exit_events = 1;806caps.can_generate_exception_events = 1;807caps.can_generate_compiled_method_load_events = 1;808caps.can_generate_field_access_events = 1;809caps.can_generate_field_modification_events = 1;810caps.can_generate_frame_pop_events = 1;811caps.can_generate_garbage_collection_events = 1;812caps.can_generate_monitor_events = 1;813caps.can_generate_native_method_bind_events = 1;814caps.can_generate_object_free_events = 1;815caps.can_generate_vm_object_alloc_events = 1;816if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps)))817return JNI_ERR;818819/* Breakpoint events */820display(0, "#### JVMTIagent: setting Breakpoint events ...\n");821822callbacks.Breakpoint = &Breakpoint;823824if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))825return JNI_ERR;826display(0, "#### JVMTIagent: ... setting Breakpoint events done\n");827828/* ClassFileLoadHook events */829display(0, "#### JVMTIagent: setting ClassFileLoadHook events ...\n");830831callbacks.ClassFileLoadHook = &ClassFileLoadHook;832833if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)))834return JNI_ERR;835display(0, "#### JVMTIagent: ... setting ClassFileLoadHook events done\n");836837/* ClassLoad events */838display(0, "#### JVMTIagent: setting ClassLoad events ...\n");839840callbacks.ClassLoad = &ClassLoad;841842if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))843return JNI_ERR;844display(0, "#### JVMTIagent: ... setting ClassLoad events done\n");845846/* ClassPrepare events */847display(0, "#### JVMTIagent: setting ClassPrepare events ...\n");848849callbacks.ClassPrepare = &ClassPrepare;850851if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL)))852return JNI_ERR;853display(0, "#### JVMTIagent: ... setting ClassPrepare events done\n");854855/* CompiledMethodLoad events */856display(0, "#### JVMTIagent: setting CompiledMethodLoad events ...\n");857858callbacks.CompiledMethodLoad = &CompiledMethodLoad;859860if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL)))861return JNI_ERR;862display(0, "#### JVMTIagent: ... setting CompiledMethodLoad events done\n");863864/* CompiledMethodUnload events */865display(0, "#### JVMTIagent: setting CompiledMethodUnload events ...\n");866867callbacks.CompiledMethodUnload = &CompiledMethodUnload;868869if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL)))870return JNI_ERR;871display(0, "#### JVMTIagent: ... setting CompiledMethodUnload events done\n");872873/* DataDumpRequest events */874display(0, "#### JVMTIagent: setting DataDumpRequest events ...\n");875876callbacks.DataDumpRequest = &DataDumpRequest;877878if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, NULL)))879return JNI_ERR;880display(0, "#### JVMTIagent: ... setting DataDumpRequest events done\n");881882/* DynamicCodeGenerated events */883display(0, "#### JVMTIagent: setting DynamicCodeGenerated events ...\n");884885callbacks.DynamicCodeGenerated = &DynamicCodeGenerated;886887if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL)))888return JNI_ERR;889display(0, "#### JVMTIagent: ... setting DynamicCodeGenerated events done\n");890891/* Exception events */892display(0, "#### JVMTIagent: setting Exception events ...\n");893894callbacks.Exception = &Exception;895896if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)))897return JNI_ERR;898display(0, "#### JVMTIagent: ... setting Exception events done\n");899900/* FieldAccess events */901display(0, "#### JVMTIagent: setting FieldAccess events ...\n");902903callbacks.FieldAccess = &FieldAccess;904905if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FIELD_ACCESS, NULL)))906return JNI_ERR;907display(0, "#### JVMTIagent: ... setting FieldAccess events done\n");908909/* FieldModification events */910display(0, "#### JVMTIagent: setting FieldModification events ...\n");911912callbacks.FieldModification = &FieldModification;913914if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FIELD_MODIFICATION, NULL)))915return JNI_ERR;916display(0, "#### JVMTIagent: ... setting FieldModification events done\n");917918/* FramePop events */919display(0, "#### JVMTIagent: setting FramePop events ...\n");920921callbacks.FramePop = &FramePop;922923if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, NULL)))924return JNI_ERR;925display(0, "#### JVMTIagent: ... setting FramePop events done\n");926927/* GarbageCollectionFinish events */928display(0, "#### JVMTIagent: setting GarbageCollectionFinish events ...\n");929930callbacks.GarbageCollectionFinish = &GarbageCollectionFinish;931932if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL)))933return JNI_ERR;934display(0, "#### JVMTIagent: ... setting GarbageCollectionFinish events done\n");935936/* GarbageCollectionStart events */937display(0, "#### JVMTIagent: setting GarbageCollectionStart events ...\n");938939callbacks.GarbageCollectionStart = &GarbageCollectionStart;940941if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL)))942return JNI_ERR;943display(0, "#### JVMTIagent: ... setting GarbageCollectionStart events done\n");944945/* MonitorContendedEnter events */946display(0, "#### JVMTIagent: setting MonitorContendedEnter events ...\n");947948callbacks.MonitorContendedEnter = &MonitorContendedEnter;949950if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL)))951return JNI_ERR;952display(0, "#### JVMTIagent: ... setting MonitorContendedEnter events done\n");953954/* MonitorContendedEntered events */955display(0, "#### JVMTIagent: setting MonitorContendedEntered events ...\n");956957callbacks.MonitorContendedEntered = &MonitorContendedEntered;958959if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL)))960return JNI_ERR;961display(0, "#### JVMTIagent: ... setting MonitorContendedEntered events done\n");962963/* MonitorWait events */964display(0, "#### JVMTIagent: setting MonitorWait events ...\n");965966callbacks.MonitorWait = &MonitorWait;967968if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL)))969return JNI_ERR;970display(0, "#### JVMTIagent: ... setting MonitorWait events done\n");971972/* MonitorWaited events */973display(0, "#### JVMTIagent: setting MonitorWaited events ...\n");974975callbacks.MonitorWaited = &MonitorWaited;976977if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL)))978return JNI_ERR;979display(0, "#### JVMTIagent: ... setting MonitorWaited events done\n");980981/* NativeMethodBind events */982display(0, "#### JVMTIagent: setting NativeMethodBind events ...\n");983984callbacks.NativeMethodBind = &NativeMethodBind;985986if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)))987return JNI_ERR;988display(0, "#### JVMTIagent: ... setting NativeMethodBind events done\n");989990/* ObjectFree events */991display(0, "#### JVMTIagent: setting ObjectFree events ...\n");992993callbacks.ObjectFree = &ObjectFree;994995if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)))996return JNI_ERR;997display(0, "#### JVMTIagent: ... setting ObjectFree events done\n");998999/* ThreadEnd events */1000display(0, "#### JVMTIagent: setting ThreadEnd events ...\n");10011002callbacks.ThreadEnd = &ThreadEnd;10031004if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL)))1005return JNI_ERR;1006display(0, "#### JVMTIagent: ... setting ThreadEnd events done\n");10071008/* ThreadStart events */1009display(0, "#### JVMTIagent: setting ThreadStart events ...\n");10101011callbacks.ThreadStart = &ThreadStart;10121013if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL)))1014return JNI_ERR;1015display(0, "#### JVMTIagent: ... setting ThreadStart events done\n");10161017/* VMDeath events */1018display(0, "#### JVMTIagent: setting VMDeath events ...\n");10191020callbacks.VMDeath = &VMDeath;10211022if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))1023return JNI_ERR;1024display(0, "#### JVMTIagent: ... setting VMDeath events done\n");10251026/* VMInit events */1027display(0, "#### JVMTIagent: setting VMInit events ...\n");10281029callbacks.VMInit = &VMInit;10301031if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL)))1032return JNI_ERR;1033display(0, "#### JVMTIagent: ... setting VMInit events done\n");10341035/* VMStart events */1036display(0, "#### JVMTIagent: setting VMStart events ...\n");10371038callbacks.VMStart = &VMStart;10391040if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))1041return JNI_ERR;1042display(0, "#### JVMTIagent: ... setting VMStart events done\n");10431044/* VMObjectAlloc events */1045display(0, "#### JVMTIagent: setting VMObjectAlloc events ...\n");10461047callbacks.VMObjectAlloc = &VMObjectAlloc;10481049if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, NULL)))1050return JNI_ERR;1051display(0, "#### JVMTIagent: ... setting VMObjectAlloc events done\n");10521053if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))1054return JNI_ERR;10551056return 0;1057}10581059static void clearJavaException(JNIEnv* jni_env) {1060if (jni_env->ExceptionOccurred()) {10611062jni_env->ExceptionDescribe();1063jni_env->ExceptionClear();10641065jni_env->FatalError("JVMTIagent: exception occurred in java code, aborting\n");1066}1067}10681069static int get_tok(char **src, char *buf, int buflen, char sep) {1070int i;1071char *p = *src;1072for (i = 0; i < buflen; i++) {1073if (p[i] == 0 || p[i] == sep) {1074buf[i] = 0;1075if (p[i] == sep) {1076i++;1077}1078*src += i;1079return i;1080}1081buf[i] = p[i];1082}1083/* overflow */1084return 0;1085}10861087static void doSetup(char *str) {1088if (str == 0)1089str = (char*) "";10901091if ((strcmp(str, "help")) == 0) {1092printf("#### JVMTIagent usage: -agentlib:JVMTIagent[=[help]|[=[verbose]|[verbose2],[stress0|stress1|stress2|stress3]]]\n");1093printf("#### where: help\tprint this message\n");1094printf("#### verbose\tturn verbose mode on\n");1095printf("#### verbose2\tturn extended verbose mode on (including reporting JVMTI events)\n");1096printf("#### stress0, or empty value\tturn stress level 0 on (default mode):\n");1097printf("#### enable event generation except ExceptionCatch, MethodEntry/Exit, SingleStep\n");1098printf("#### stress1\tturn stress level 1 on:\n");1099printf("#### enable generation of ExceptionCatch events\n");1100printf("#### stress2\tturn stress level 2 on:\n");1101printf("#### enable generation of ExceptionCatch,\n");1102printf("#### MethodEntry/Exit events\n");1103printf("#### stress3\tturn stress level 3 on:\n");1104printf("#### enable generation of ExceptionCatch,\n");1105printf("#### MethodEntry/Exit,\n");1106printf("#### SingleStep events\n");1107exit(1);1108}11091110while (*str) {1111char buf[1000];11121113if (!get_tok(&str, buf, sizeof(buf), ',')) {1114printf("ERROR: JVMTIagent: bad option: \"%s\"!\n", str);1115exit(1);1116}1117if ((strcmp(buf, "verbose")) == 0) {1118printf("#### JVMTIagent: turned verbose mode on ####\n");1119debug_mode = 1;1120}1121if ((strcmp(buf, "verbose2")) == 0) {1122printf("#### JVMTIagent: turned extended verbose mode on ####\n");1123debug_mode = 2;1124}1125if ((strcmp(buf, "stress0")) == 0) {1126if (debug_mode > 0)1127printf("#### JVMTIagent: turned stress level 0 on ####\n");1128stress_lev = 0;1129}1130if ((strcmp(buf, "stress1")) == 0) {1131if (debug_mode > 0)1132printf("#### JVMTIagent: turned stress level 1 on ####\n");1133stress_lev = 1;1134}1135if ((strcmp(buf, "stress2")) == 0) {1136if (debug_mode > 0)1137printf("#### JVMTIagent: turned stress level 2 on ####\n");1138stress_lev = 2;1139}1140if ((strcmp(buf, "stress3")) == 0) {1141if (debug_mode > 0)1142printf("#### JVMTIagent: turned stress level 3 on ####\n");1143stress_lev = 3;1144}1145}1146}11471148static void getVerdict(JNIEnv *jni_env, const char *evnt) {1149char error_msg[80];11501151if (vm_death_occured == TRUE) {1152sprintf(error_msg, "JVMTIagent: getVerdict: %s event occured after VMDeath",1153evnt);11541155if (jni_env == NULL) { /* some event callbacks have no pointer to jni */1156printf("ERROR: %s\n", error_msg);1157exit(97);1158}1159else1160jni_env->FatalError(error_msg);1161}1162}11631164static void display(int level, const char format[], ...) {1165va_list ar;11661167if (debug_mode > level) {1168va_start(ar, format);1169vprintf(format, ar);1170va_end(ar);1171}1172}11731174/* agent procedure */1175static void JNICALL1176agentProc(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg) {1177}11781179JNIEXPORT jint JNICALL1180Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {1181/* create JVMTI environment */1182if (!NSK_VERIFY((jvmti =1183nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))1184return JNI_ERR;11851186doSetup(options);11871188if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_event_lock", &eventLock)))1189return JNI_ERR;11901191if (enableEventsCaps() == 0 && addStressEvents() == 0) {1192display(0, "#### JVMTIagent: all events were successfully enabled and capabilities/events callbacks set ####\n\n");1193} else {1194printf("ERROR(%s,%d): JVMTIagent terminated abnormally! ####\n",1195__FILE__,__LINE__);1196return JNI_ERR;1197}11981199/* register agent proc and arg */1200if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))1201return JNI_ERR;12021203return JNI_OK;1204}12051206}120712081209