Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FieldAccess/fieldacc003/fieldacc003.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/fieldacc003a;", "run", "()I", 3,69"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsBoolean", "Z", JNI_FALSE },70{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 14,71"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsByte", "B", JNI_FALSE },72{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 25,73"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsShort", "S", JNI_FALSE },74{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 36,75"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsInt", "I", JNI_FALSE },76{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 47,77"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsLong", "J", JNI_FALSE },78{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 61,79"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsFloat", "F", JNI_FALSE },80{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 74,81"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsDouble", "D", JNI_FALSE },82{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 88,83"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsChar", "C", JNI_FALSE },84{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 100,85"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsObject", "Ljava/lang/Object;", JNI_FALSE },86{ NULL, "Lnsk/jvmti/FieldAccess/fieldacc003a;", "run", "()I", 111,87"Lnsk/jvmti/FieldAccess/fieldacc003a;", "extendsArrInt", "[I", JNI_FALSE }88};8990void JNICALL FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,91jthread thr, jmethodID method,92jlocation location, jclass field_klass, jobject obj, jfieldID field) {93jvmtiError err;94jclass cls;95writable_watch_info watch;96char *generic;97size_t i;9899eventsCount++;100if (printdump == JNI_TRUE) {101printf(">>> retrieving access watch info ...\n");102}103watch.fid = field;104watch.loc = location;105watch.is_static = (obj == NULL) ? JNI_TRUE : JNI_FALSE;106err = jvmti_env->GetMethodDeclaringClass(method, &cls);107if (err != JVMTI_ERROR_NONE) {108printf("(GetMethodDeclaringClass) unexpected error: %s (%d)\n",109TranslateError(err), err);110result = STATUS_FAILED;111return;112}113err = jvmti_env->GetClassSignature(cls,114&watch.m_cls, &generic);115if (err != JVMTI_ERROR_NONE) {116printf("(GetClassSignature) unexpected error: %s (%d)\n",117TranslateError(err), err);118result = STATUS_FAILED;119return;120}121err = jvmti_env->GetMethodName(method,122&watch.m_name, &watch.m_sig, &generic);123if (err != JVMTI_ERROR_NONE) {124printf("(GetMethodName) unexpected error: %s (%d)\n",125TranslateError(err), err);126result = STATUS_FAILED;127return;128}129err = jvmti_env->GetClassSignature(field_klass,130&watch.f_cls, &generic);131if (err != JVMTI_ERROR_NONE) {132printf("(GetClassSignature) unexpected error: %s (%d)\n",133TranslateError(err), err);134result = STATUS_FAILED;135return;136}137err = jvmti_env->GetFieldName(field_klass, field,138&watch.f_name, &watch.f_sig, &generic);139if (err != JVMTI_ERROR_NONE) {140printf("(GetFieldName) unexpected error: %s (%d)\n",141TranslateError(err), err);142result = STATUS_FAILED;143return;144}145if (printdump == JNI_TRUE) {146printf(">>> class: \"%s\"\n", watch.m_cls);147printf(">>> method: \"%s%s\"\n", watch.m_name, watch.m_sig);148printf(">>> location: 0x%x%08x\n",149(jint)(watch.loc >> 32), (jint)watch.loc);150printf(">>> field cls: \"%s\"\n", watch.f_cls);151printf(">>> field: \"%s:%s\"\n", watch.f_name, watch.f_sig);152printf(">>> object: 0x%p\n", obj);153printf(">>> ... done\n");154}155for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {156if (watch.fid == watches[i].fid) {157if (watch.m_cls == NULL ||158strcmp(watch.m_cls, watches[i].m_cls) != 0) {159printf("(watch#%" PRIuPTR ") wrong class: \"%s\", expected: \"%s\"\n",160i, watch.m_cls, watches[i].m_cls);161result = STATUS_FAILED;162}163if (watch.m_name == NULL ||164strcmp(watch.m_name, watches[i].m_name) != 0) {165printf("(watch#%" PRIuPTR ") wrong method name: \"%s\"",166i, watch.m_name);167printf(", expected: \"%s\"\n", watches[i].m_name);168result = STATUS_FAILED;169}170if (watch.m_sig == NULL ||171strcmp(watch.m_sig, watches[i].m_sig) != 0) {172printf("(watch#%" PRIuPTR ") wrong method sig: \"%s\"",173i, watch.m_sig);174printf(", expected: \"%s\"\n", watches[i].m_sig);175result = STATUS_FAILED;176}177if (watch.loc != watches[i].loc) {178printf("(watch#%" PRIuPTR ") wrong location: 0x%x%08x",179i, (jint)(watch.loc >> 32), (jint)watch.loc);180printf(", expected: 0x%x%08x\n",181(jint)(watches[i].loc >> 32), (jint)watches[i].loc);182result = STATUS_FAILED;183}184if (watch.f_name == NULL ||185strcmp(watch.f_name, watches[i].f_name) != 0) {186printf("(watch#%" PRIuPTR ") wrong field name: \"%s\"",187i, watch.f_name);188printf(", expected: \"%s\"\n", watches[i].f_name);189result = STATUS_FAILED;190}191if (watch.f_sig == NULL ||192strcmp(watch.f_sig, watches[i].f_sig) != 0) {193printf("(watch#%" PRIuPTR ") wrong field sig: \"%s\"",194i, watch.f_sig);195printf(", expected: \"%s\"\n", watches[i].f_sig);196result = STATUS_FAILED;197}198if (watch.is_static != watches[i].is_static) {199printf("(watch#%" PRIuPTR ") wrong field type: %s", i,200(watch.is_static == JNI_TRUE) ? "static" : "instance");201printf(", expected: %s\n",202(watches[i].is_static == JNI_TRUE) ? "static" : "instance");203result = STATUS_FAILED;204}205return;206}207}208printf("Unexpected field access catched: 0x%p\n", watch.fid);209result = STATUS_FAILED;210}211212#ifdef STATIC_BUILD213JNIEXPORT jint JNICALL Agent_OnLoad_fieldacc003(JavaVM *jvm, char *options, void *reserved) {214return Agent_Initialize(jvm, options, reserved);215}216JNIEXPORT jint JNICALL Agent_OnAttach_fieldacc003(JavaVM *jvm, char *options, void *reserved) {217return Agent_Initialize(jvm, options, reserved);218}219JNIEXPORT jint JNI_OnLoad_fieldacc003(JavaVM *jvm, char *options, void *reserved) {220return JNI_VERSION_1_8;221}222#endif223jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {224jvmtiError err;225jint res;226227if (options != NULL && strcmp(options, "printdump") == 0) {228printdump = JNI_TRUE;229}230231res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);232if (res != JNI_OK || jvmti == NULL) {233printf("Wrong result of a valid call to GetEnv!\n");234return JNI_ERR;235}236237err = jvmti->GetPotentialCapabilities(&caps);238if (err != JVMTI_ERROR_NONE) {239printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n",240TranslateError(err), err);241return JNI_ERR;242}243244err = jvmti->AddCapabilities(&caps);245if (err != JVMTI_ERROR_NONE) {246printf("(AddCapabilities) unexpected error: %s (%d)\n",247TranslateError(err), err);248return JNI_ERR;249}250251err = jvmti->GetCapabilities(&caps);252if (err != JVMTI_ERROR_NONE) {253printf("(GetCapabilities) unexpected error: %s (%d)\n",254TranslateError(err), err);255return JNI_ERR;256}257258if (caps.can_generate_field_access_events) {259callbacks.FieldAccess = &FieldAccess;260err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));261if (err != JVMTI_ERROR_NONE) {262printf("(SetEventCallbacks) unexpected error: %s (%d)\n",263TranslateError(err), err);264return JNI_ERR;265}266267err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,268JVMTI_EVENT_FIELD_ACCESS, NULL);269if (err != JVMTI_ERROR_NONE) {270printf("Failed to enable JVMTI_EVENT_FIELD_ACCESS: %s (%d)\n",271TranslateError(err), err);272return JNI_ERR;273}274} else {275printf("Warning: FieldAccess watch is not implemented\n");276}277278return JNI_OK;279}280281JNIEXPORT void JNICALL282Java_nsk_jvmti_FieldAccess_fieldacc003_getReady(JNIEnv *env, jclass klass) {283jvmtiError err;284jclass cls;285size_t i;286287if (!caps.can_generate_field_access_events) {288return;289}290291if (printdump == JNI_TRUE) {292printf(">>> setting field access watches ...\n");293}294for (i = 0; i < sizeof(watches)/sizeof(watch_info); i++) {295cls = env->FindClass(watches[i].f_cls);296if (cls == NULL) {297printf("Cannot find %s class!\n", watches[i].f_cls);298result = STATUS_FAILED;299return;300}301if (watches[i].is_static == JNI_TRUE) {302watches[i].fid = env->GetStaticFieldID(303cls, watches[i].f_name, watches[i].f_sig);304} else {305watches[i].fid = env->GetFieldID(306cls, watches[i].f_name, watches[i].f_sig);307}308if (watches[i].fid == NULL) {309printf("Cannot get field ID for \"%s:%s\"\n",310watches[i].f_name, watches[i].f_sig);311result = STATUS_FAILED;312return;313}314err = jvmti->SetFieldAccessWatch(cls, watches[i].fid);315if (err == JVMTI_ERROR_NONE) {316eventsExpected++;317} else {318printf("(SetFieldAccessWatch#%" PRIuPTR ") unexpected error: %s (%d)\n",319i, TranslateError(err), err);320result = STATUS_FAILED;321}322}323if (printdump == JNI_TRUE) {324printf(">>> ... done\n");325}326}327328JNIEXPORT jint JNICALL329Java_nsk_jvmti_FieldAccess_fieldacc003_check(JNIEnv *env, jclass cls) {330if (eventsCount != eventsExpected) {331printf("Wrong number of field access events: %d, expected: %d\n",332eventsCount, eventsExpected);333result = STATUS_FAILED;334}335return result;336}337338}339340341