Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FieldAccess/fieldacc001/fieldacc001.cpp
40951 views
/*1* Copyright (c) 2003, 2020, 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#include <stdio.h>24#include <string.h>25#include <inttypes.h>26#include "jvmti.h"27#include "agent_common.h"28#include "JVMTITools.h"2930extern "C" {313233#define PASSED 034#define STATUS_FAILED 23536typedef struct {37jfieldID fid;38char *m_cls;39char *m_name;40char *m_sig;41jlocation loc;42char *f_cls;43char *f_name;44char *f_sig;45jboolean is_static;46} writable_watch_info;4748typedef struct {49jfieldID fid;50const char *m_cls;51const char *m_name;52const char *m_sig;53jlocation loc;54const char *f_cls;55const char *f_name;56const char *f_sig;57jboolean is_static;58} watch_info;5960static jvmtiEnv *jvmti;61static jvmtiEventCallbacks callbacks;62static jvmtiCapabilities caps;63static jint result = PASSED;64static jboolean printdump = JNI_FALSE;65static int eventsExpected = 0;66static int eventsCount = 0;67static watch_info watches[] = {68{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 2,69"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticBoolean", "Z", JNI_TRUE },70{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 6,71"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceBoolean", "Z", JNI_FALSE },72{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 15,73"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticByte", "B", JNI_TRUE },74{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 19,75"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceByte", "B", JNI_FALSE },76{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 28,77"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticShort", "S", JNI_TRUE },78{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 32,79"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceShort", "S", JNI_FALSE },80{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 41,81"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticInt", "I", JNI_TRUE },82{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 45,83"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceInt", "I", JNI_FALSE },84{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 54,85"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticLong", "J", JNI_TRUE },86{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 58,87"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceLong", "J", JNI_FALSE },88{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 68,89"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticFloat", "F", JNI_TRUE },90{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 72,91"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceFloat", "F", JNI_FALSE },92{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 82,93"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticDouble", "D", JNI_TRUE },94{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 86,95"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceDouble", "D", JNI_FALSE },96{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 96,97"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticChar", "C", JNI_TRUE },98{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 100,99"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceChar", "C", JNI_FALSE },100{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 109,101"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticObject", "Ljava/lang/Object;", JNI_TRUE },102{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 113,103"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceObject", "Ljava/lang/Object;", JNI_FALSE },104{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 122,105"Lnsk/jvmti/FieldAccess/fieldacc001a;", "staticArrInt", "[I", JNI_TRUE },106{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc001a;", "run", "()I", 128,107"Lnsk/jvmti/FieldAccess/fieldacc001a;", "instanceArrInt", "[I", JNI_FALSE }108};109110111void JNICALL FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,112jthread thr, jmethodID method,113jlocation location, jclass field_klass, jobject obj, jfieldID field) {114jvmtiError err;115jclass cls;116writable_watch_info watch;117char *generic;118size_t i;119120eventsCount++;121if (printdump == JNI_TRUE) {122printf(">>> retrieving access watch info ...\n");123}124watch.fid = field;125watch.loc = location;126watch.is_static = (obj == NULL) ? JNI_TRUE : JNI_FALSE;127err = jvmti_env->GetMethodDeclaringClass(method, &cls);128if (err != JVMTI_ERROR_NONE) {129printf("(GetMethodDeclaringClass) unexpected error: %s (%d)\n",130TranslateError(err), err);131result = STATUS_FAILED;132return;133}134err = jvmti_env->GetClassSignature(cls,135&watch.m_cls, &generic);136if (err != JVMTI_ERROR_NONE) {137printf("(GetClassSignature) unexpected error: %s (%d)\n",138TranslateError(err), err);139result = STATUS_FAILED;140return;141}142err = jvmti_env->GetMethodName(method,143&watch.m_name, &watch.m_sig, &generic);144if (err != JVMTI_ERROR_NONE) {145printf("(GetMethodName) unexpected error: %s (%d)\n",146TranslateError(err), err);147result = STATUS_FAILED;148return;149}150err = jvmti_env->GetClassSignature(field_klass,151&watch.f_cls, &generic);152if (err != JVMTI_ERROR_NONE) {153printf("(GetClassSignature) unexpected error: %s (%d)\n",154TranslateError(err), err);155result = STATUS_FAILED;156return;157}158err = jvmti_env->GetFieldName(field_klass, field,159&watch.f_name, &watch.f_sig, &generic);160if (err != JVMTI_ERROR_NONE) {161printf("(GetFieldName) unexpected error: %s (%d)\n",162TranslateError(err), err);163result = STATUS_FAILED;164return;165}166if (printdump == JNI_TRUE) {167printf(">>> class: \"%s\"\n", watch.m_cls);168printf(">>> method: \"%s%s\"\n", watch.m_name, watch.m_sig);169printf(">>> location: 0x%x%08x\n",170(jint)(watch.loc >> 32), (jint)watch.loc);171printf(">>> field cls: \"%s\"\n", watch.f_cls);172printf(">>> field: \"%s:%s\"\n", watch.f_name, watch.f_sig);173printf(">>> object: 0x%p\n", obj);174printf(">>> ... done\n");175}176for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {177if (watch.fid == watches[i].fid) {178if (watch.m_cls == NULL ||179strcmp(watch.m_cls, watches[i].m_cls) != 0) {180printf("(watch#%" PRIuPTR ") wrong class: \"%s\", expected: \"%s\"\n",181i, watch.m_cls, watches[i].m_cls);182result = STATUS_FAILED;183}184if (watch.m_name == NULL ||185strcmp(watch.m_name, watches[i].m_name) != 0) {186printf("(watch#%" PRIuPTR ") wrong method name: \"%s\"",187i, watch.m_name);188printf(", expected: \"%s\"\n", watches[i].m_name);189result = STATUS_FAILED;190}191if (watch.m_sig == NULL ||192strcmp(watch.m_sig, watches[i].m_sig) != 0) {193printf("(watch#%" PRIuPTR ") wrong method sig: \"%s\"",194i, watch.m_sig);195printf(", expected: \"%s\"\n", watches[i].m_sig);196result = STATUS_FAILED;197}198if (watch.loc != watches[i].loc) {199printf("(watch#%" PRIuPTR ") wrong location: 0x%x%08x",200i, (jint)(watch.loc >> 32), (jint)watch.loc);201printf(", expected: 0x%x%08x\n",202(jint)(watches[i].loc >> 32), (jint)watches[i].loc);203result = STATUS_FAILED;204}205if (watch.f_name == NULL ||206strcmp(watch.f_name, watches[i].f_name) != 0) {207printf("(watch#%" PRIuPTR ") wrong field name: \"%s\"",208i, watch.f_name);209printf(", expected: \"%s\"\n", watches[i].f_name);210result = STATUS_FAILED;211}212if (watch.f_sig == NULL ||213strcmp(watch.f_sig, watches[i].f_sig) != 0) {214printf("(watch#%" PRIuPTR ") wrong field sig: \"%s\"",215i, watch.f_sig);216printf(", expected: \"%s\"\n", watches[i].f_sig);217result = STATUS_FAILED;218}219if (watch.is_static != watches[i].is_static) {220printf("(watch#%" PRIuPTR ") wrong field type: %s", i,221(watch.is_static == JNI_TRUE) ? "static" : "instance");222printf(", expected: %s\n",223(watches[i].is_static == JNI_TRUE) ? "static" : "instance");224result = STATUS_FAILED;225}226return;227}228}229printf("Unexpected field access catched: 0x%p\n", watch.fid);230result = STATUS_FAILED;231}232233#ifdef STATIC_BUILD234JNIEXPORT jint JNICALL Agent_OnLoad_fieldacc001(JavaVM *jvm, char *options, void *reserved) {235return Agent_Initialize(jvm, options, reserved);236}237JNIEXPORT jint JNICALL Agent_OnAttach_fieldacc001(JavaVM *jvm, char *options, void *reserved) {238return Agent_Initialize(jvm, options, reserved);239}240JNIEXPORT jint JNI_OnLoad_fieldacc001(JavaVM *jvm, char *options, void *reserved) {241return JNI_VERSION_1_8;242}243#endif244jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {245jvmtiError err;246jint res;247248if (options != NULL && strcmp(options, "printdump") == 0) {249printdump = JNI_TRUE;250}251252res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);253if (res != JNI_OK || jvmti == NULL) {254printf("Wrong result of a valid call to GetEnv!\n");255return JNI_ERR;256}257258err = jvmti->GetPotentialCapabilities(&caps);259if (err != JVMTI_ERROR_NONE) {260printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",261TranslateError(err), err);262return JNI_ERR;263}264265err = jvmti->AddCapabilities(&caps);266if (err != JVMTI_ERROR_NONE) {267printf("(AddCapabilities) unexpected error: %s (%d)\n",268TranslateError(err), err);269return JNI_ERR;270}271272err = jvmti->GetCapabilities(&caps);273if (err != JVMTI_ERROR_NONE) {274printf("(GetCapabilities) unexpected error: %s (%d)\n",275TranslateError(err), err);276return JNI_ERR;277}278279if (caps.can_generate_field_access_events) {280callbacks.FieldAccess = &FieldAccess;281err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));282if (err != JVMTI_ERROR_NONE) {283printf("(SetEventCallbacks) unexpected error: %s (%d)\n",284TranslateError(err), err);285return JNI_ERR;286}287288err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,289JVMTI_EVENT_FIELD_ACCESS, NULL);290if (err != JVMTI_ERROR_NONE) {291printf("Failed to enable JVMTI_EVENT_FIELD_ACCESS: %s (%d)\n",292TranslateError(err), err);293return JNI_ERR;294}295} else {296printf("Warning: FieldAccess watch is not implemented\n");297}298299return JNI_OK;300}301302303JNIEXPORT void JNICALL304Java_nsk_jvmti_FieldAccess_fieldacc001_getReady(JNIEnv *env, jclass klass) {305jvmtiError err;306jclass cls;307size_t i;308309if (!caps.can_generate_field_access_events) {310return;311}312313if (printdump == JNI_TRUE) {314printf(">>> setting field access watches ...\n");315}316cls = env->FindClass("nsk/jvmti/FieldAccess/fieldacc001a");317if (cls == NULL) {318printf("Cannot find fieldacc001a class!\n");319result = STATUS_FAILED;320return;321}322for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {323if (watches[i].is_static == JNI_TRUE) {324watches[i].fid = env->GetStaticFieldID(325cls, watches[i].f_name, watches[i].f_sig);326} else {327watches[i].fid = env->GetFieldID(328cls, watches[i].f_name, watches[i].f_sig);329}330if (watches[i].fid == NULL) {331printf("Cannot find field \"%s\"!\n", watches[i].f_name);332result = STATUS_FAILED;333return;334}335err = jvmti->SetFieldAccessWatch(cls, watches[i].fid);336if (err == JVMTI_ERROR_NONE) {337eventsExpected++;338} else {339printf("(SetFieldAccessWatch#%" PRIuPTR ") unexpected error: %s (%d)\n",340i, TranslateError(err), err);341result = STATUS_FAILED;342}343}344if (printdump == JNI_TRUE) {345printf(">>> ... done\n");346}347}348349JNIEXPORT jint JNICALL350Java_nsk_jvmti_FieldAccess_fieldacc001_check(JNIEnv *env, jclass cls) {351if (eventsCount != eventsExpected) {352printf("Wrong number of field access events: %d, expected: %d\n",353eventsCount, eventsExpected);354result = STATUS_FAILED;355}356return result;357}358359}360361362