Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FieldAccess/fieldacc002/fieldacc002.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/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,69"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticBoolean", "Z", JNI_TRUE },70{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,71"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticByte", "B", JNI_TRUE },72{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,73"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticShort", "S", JNI_TRUE },74{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,75"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticInt", "I", JNI_TRUE },76{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,77"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticLong", "J", JNI_TRUE },78{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,79"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticFloat", "F", JNI_TRUE },80{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,81"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticDouble", "D", JNI_TRUE },82{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,83"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticChar", "C", JNI_TRUE },84{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,85"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticObject", "Ljava/lang/Object;", JNI_TRUE },86{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,87"Lnsk/jvmti/FieldAccess/fieldacc002a;", "staticArrInt", "[I", JNI_TRUE },8889{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,90"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceBoolean", "Z", JNI_FALSE },91{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,92"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceByte", "B", JNI_FALSE },93{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,94"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceShort", "S", JNI_FALSE },95{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,96"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceInt", "I", JNI_FALSE },97{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,98"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceLong", "J", JNI_FALSE },99{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,100"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceFloat", "F", JNI_FALSE },101{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,102"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceDouble", "D", JNI_FALSE },103{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,104"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceChar", "C", JNI_FALSE },105{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,106"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceObject", "Ljava/lang/Object;", JNI_FALSE },107{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc002;", "check", "(Ljava/lang/Object;)I", 0,108"Lnsk/jvmti/FieldAccess/fieldacc002a;", "instanceArrInt", "[I", JNI_FALSE }109};110111void 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);174}175for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {176if (watch.fid == watches[i].fid) {177if (watch.m_cls == NULL ||178strcmp(watch.m_cls, watches[i].m_cls) != 0) {179printf("(watch#%" PRIuPTR ") wrong class: \"%s\", expected: \"%s\"\n",180i, watch.m_cls, watches[i].m_cls);181result = STATUS_FAILED;182}183if (watch.m_name == NULL ||184strcmp(watch.m_name, watches[i].m_name) != 0) {185printf("(watch#%" PRIuPTR ") wrong method name: \"%s\"",186i, watch.m_name);187printf(", expected: \"%s\"\n", watches[i].m_name);188result = STATUS_FAILED;189}190if (watch.m_sig == NULL ||191strcmp(watch.m_sig, watches[i].m_sig) != 0) {192printf("(watch#%" PRIuPTR ") wrong method sig: \"%s\"",193i, watch.m_sig);194printf(", expected: \"%s\"\n", watches[i].m_sig);195result = STATUS_FAILED;196}197if (watch.loc != watches[i].loc) {198printf("(watch#%" PRIuPTR ") wrong location: 0x%x%08x",199i, (jint)(watch.loc >> 32), (jint)watch.loc);200printf(", expected: 0x%x%08x\n",201(jint)(watches[i].loc >> 32), (jint)watches[i].loc);202result = STATUS_FAILED;203}204if (watch.f_name == NULL ||205strcmp(watch.f_name, watches[i].f_name) != 0) {206printf("(watch#%" PRIuPTR ") wrong field name: \"%s\"",207i, watch.f_name);208printf(", expected: \"%s\"\n", watches[i].f_name);209result = STATUS_FAILED;210}211if (watch.f_sig == NULL ||212strcmp(watch.f_sig, watches[i].f_sig) != 0) {213printf("(watch#%" PRIuPTR ") wrong field sig: \"%s\"",214i, watch.f_sig);215printf(", expected: \"%s\"\n", watches[i].f_sig);216result = STATUS_FAILED;217}218if (watch.is_static != watches[i].is_static) {219printf("(watch#%" PRIuPTR ") wrong field type: %s", i,220(watch.is_static == JNI_TRUE) ? "static" : "instance");221printf(", expected: %s\n",222(watches[i].is_static == JNI_TRUE) ? "static" : "instance");223result = STATUS_FAILED;224}225return;226}227}228printf("Unexpected field access catched: 0x%p\n", watch.fid);229result = STATUS_FAILED;230}231232#ifdef STATIC_BUILD233JNIEXPORT jint JNICALL Agent_OnLoad_fieldacc002(JavaVM *jvm, char *options, void *reserved) {234return Agent_Initialize(jvm, options, reserved);235}236JNIEXPORT jint JNICALL Agent_OnAttach_fieldacc002(JavaVM *jvm, char *options, void *reserved) {237return Agent_Initialize(jvm, options, reserved);238}239JNIEXPORT jint JNI_OnLoad_fieldacc002(JavaVM *jvm, char *options, void *reserved) {240return JNI_VERSION_1_8;241}242#endif243jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {244jvmtiError err;245jint res;246247if (options != NULL && strcmp(options, "printdump") == 0) {248printdump = JNI_TRUE;249}250251res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);252if (res != JNI_OK || jvmti == NULL) {253printf("Wrong result of a valid call to GetEnv!\n");254return JNI_ERR;255}256257err = jvmti->GetPotentialCapabilities(&caps);258if (err != JVMTI_ERROR_NONE) {259printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",260TranslateError(err), err);261return JNI_ERR;262}263264err = jvmti->AddCapabilities(&caps);265if (err != JVMTI_ERROR_NONE) {266printf("(AddCapabilities) unexpected error: %s (%d)\n",267TranslateError(err), err);268return JNI_ERR;269}270271err = jvmti->GetCapabilities(&caps);272if (err != JVMTI_ERROR_NONE) {273printf("(GetCapabilities) unexpected error: %s (%d)\n",274TranslateError(err), err);275return JNI_ERR;276}277278if (caps.can_generate_field_access_events) {279callbacks.FieldAccess = &FieldAccess;280err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));281if (err != JVMTI_ERROR_NONE) {282printf("(SetEventCallbacks) unexpected error: %s (%d)\n",283TranslateError(err), err);284return JNI_ERR;285}286287err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,288JVMTI_EVENT_FIELD_ACCESS, NULL);289if (err != JVMTI_ERROR_NONE) {290printf("Failed to enable JVMTI_EVENT_FIELD_ACCESS: %s (%d)\n",291TranslateError(err), err);292return JNI_ERR;293}294} else {295printf("Warning: FieldAccess watch is not implemented\n");296}297298return JNI_OK;299}300301JNIEXPORT void JNICALL Java_nsk_jvmti_FieldAccess_fieldacc002_getReady(JNIEnv *env, jclass clz) {302jvmtiError err;303jclass cls;304size_t i;305306if (!caps.can_generate_field_access_events) {307return;308}309310if (printdump == JNI_TRUE) {311printf(">>> setting field access watches ...\n");312}313314cls = env->FindClass("nsk/jvmti/FieldAccess/fieldacc002a");315if (cls == NULL) {316printf("Cannot find fieldacc002a class!\n");317result = STATUS_FAILED;318return;319}320for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {321if (watches[i].is_static == JNI_TRUE) {322watches[i].fid = env->GetStaticFieldID(323cls, watches[i].f_name, watches[i].f_sig);324} else {325watches[i].fid = env->GetFieldID(326cls, watches[i].f_name, watches[i].f_sig);327}328if (watches[i].fid == NULL) {329printf("Cannot find field \"%s\"!\n", watches[i].f_name);330result = STATUS_FAILED;331return;332}333err = jvmti->SetFieldAccessWatch(cls, watches[i].fid);334if (err == JVMTI_ERROR_NONE) {335eventsExpected++;336} else {337printf("(SetFieldAccessWatch#%" PRIuPTR ") unexpected error: %s (%d)\n",338i, TranslateError(err), err);339result = STATUS_FAILED;340}341}342343if (printdump == JNI_TRUE) {344printf(">>> ... done\n");345}346}347348JNIEXPORT jint JNICALL349Java_nsk_jvmti_FieldAccess_fieldacc002_check(JNIEnv *env, jclass clz, jobject obj) {350jclass cls;351352if (!caps.can_generate_field_access_events) {353return result;354}355356if (printdump == JNI_TRUE) {357printf(">>> accessing fields ...\n");358}359360cls = env->FindClass("nsk/jvmti/FieldAccess/fieldacc002a");361if (cls == NULL) {362printf("Cannot find fieldacc002a class!\n");363return STATUS_FAILED;364}365366env->GetStaticBooleanField(cls, watches[0].fid);367env->GetStaticByteField(cls, watches[1].fid);368env->GetStaticShortField(cls, watches[2].fid);369env->GetStaticIntField(cls, watches[3].fid);370env->GetStaticLongField(cls, watches[4].fid);371env->GetStaticFloatField(cls, watches[5].fid);372env->GetStaticDoubleField(cls, watches[6].fid);373env->GetStaticCharField(cls, watches[7].fid);374env->GetStaticObjectField(cls, watches[8].fid);375env->GetStaticObjectField(cls, watches[9].fid);376377env->GetBooleanField(obj, watches[10].fid);378env->GetByteField(obj, watches[11].fid);379env->GetShortField(obj, watches[12].fid);380env->GetIntField(obj, watches[13].fid);381env->GetLongField(obj, watches[14].fid);382env->GetFloatField(obj, watches[15].fid);383env->GetDoubleField(obj, watches[16].fid);384env->GetCharField(obj, watches[17].fid);385env->GetObjectField(obj, watches[18].fid);386env->GetObjectField(obj, watches[19].fid);387388if (printdump == JNI_TRUE) {389printf(">>> ... done\n");390}391392if (eventsCount != eventsExpected) {393printf("Wrong number of field access events: %d, expected: %d\n",394eventsCount, eventsExpected);395result = STATUS_FAILED;396}397return result;398}399400}401402403