Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ClassFileLoadHook/classfloadhk002/classfloadhk002.cpp
40955 views
/*1* Copyright (c) 2003, 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#include <string.h>24#include "jvmti.h"25#include "agent_common.h"26#include "jni_tools.h"27#include "jvmti_tools.h"2829extern "C" {3031/* ============================================================================= */3233/* scaffold objects */34static jlong timeout = 0;3536/* constant names */37#define DEBUGEE_CLASS_NAME "nsk/jvmti/ClassFileLoadHook/classfloadhk002"38#define TESTED_CLASS_NAME "nsk/jvmti/ClassFileLoadHook/classfloadhk002r"39#define TESTED_CLASS_SIG "L" TESTED_CLASS_NAME ";"40#define BYTECODE_FIELD_SIG "[B"41#define ORIG_BYTECODE_FIELD_NAME "origClassBytes"4243static unsigned char* origClassBytes = NULL;44static jint origClassSize = 0;4546static volatile int eventsCount = 0;4748/* ============================================================================= */4950/** Check (strictly or not) if bytecode has expected size and bytes or complain an error. */51static int checkBytecode(const char kind[], jint size, const unsigned char bytes[],52jint expectedSize, const unsigned char expectedBytes[],53int strict) {54int success = NSK_TRUE;5556NSK_DISPLAY3("Check %s bytecode: 0x%p:%d\n", kind, (void*)bytes, (int)size);57if (nsk_getVerboseMode()) {58nsk_printHexBytes(" ", 16, size, bytes);59}6061if (bytes == NULL) {62NSK_COMPLAIN2("Unexpected NULL pointer to %s bytecode in CLASS_FILE_LOAD_HOOK: 0x%p\n",63kind, (void*)bytes);64return NSK_FALSE;65}6667if (size <= 0) {68NSK_COMPLAIN2("Unexpected zero size of %s bytecode in CLASS_FILE_LOAD_HOOK: %d\n",69kind, (int)size);70return NSK_FALSE;71}7273if (strict) {74if (size != expectedSize) {75NSK_COMPLAIN3("Unexpected size of %s bytecode in CLASS_FILE_LOAD_HOOK:\n"76"# got size: %d\n"77"# expected: %d\n",78kind, (int)size, (int)expectedSize);79success = NSK_FALSE;80} else {81jint different = 0;82jint i;8384for (i = 0; i < size; i++) {85if (bytes[i] != expectedBytes[i]) {86different++;87}88}89if (different > 0) {90NSK_COMPLAIN2("Unexpected bytes in %s bytecode in CLASS_FILE_LOAD_HOOK:\n"91"# different bytes: %d\n"92"# total bytes: %d\n",93(int)different, (int)size);94success = NSK_FALSE;95}96}9798if (!success) {99NSK_COMPLAIN2("Got %s bytecode is not equal to expected bytecode: %d bytes\n",100kind, expectedSize);101if (nsk_getVerboseMode()) {102nsk_printHexBytes(" ", 16, expectedSize, expectedBytes);103}104} else {105NSK_DISPLAY1("All %s bytecode is equal to expected one\n", kind);106}107}108109return success;110}111112/** Get classfile bytecode from a static field of given class. */113static int getBytecode(jvmtiEnv* jvmti, JNIEnv* jni, jclass cls,114const char fieldName[], const char fieldSig[],115jint* size, unsigned char* *bytes) {116117jfieldID fieldID = NULL;118jbyteArray array = NULL;119jbyte* elements;120int i;121122NSK_DISPLAY1("Find static field: %s\n", fieldName);123if (!NSK_JNI_VERIFY(jni, (fieldID =124jni->GetStaticFieldID(cls, fieldName, fieldSig)) != NULL)) {125nsk_jvmti_setFailStatus();126return NSK_FALSE;127}128NSK_DISPLAY1(" ... got fieldID: 0x%p\n", (void*)fieldID);129130NSK_DISPLAY1("Get classfile bytes array from static field: %s\n", fieldName);131if (!NSK_JNI_VERIFY(jni, (array = (jbyteArray)132jni->GetStaticObjectField(cls, fieldID)) != NULL)) {133nsk_jvmti_setFailStatus();134return NSK_FALSE;135}136NSK_DISPLAY1(" ... got array object: 0x%p\n", (void*)array);137138if (!NSK_JNI_VERIFY(jni, (*size = jni->GetArrayLength(array)) > 0)) {139nsk_jvmti_setFailStatus();140return NSK_FALSE;141}142NSK_DISPLAY1(" ... got array size: %d bytes\n", (int)*size);143144{145jboolean isCopy;146if (!NSK_JNI_VERIFY(jni, (elements = jni->GetByteArrayElements(array, &isCopy)) != NULL)) {147nsk_jvmti_setFailStatus();148return NSK_FALSE;149}150}151NSK_DISPLAY1(" ... got elements list: 0x%p\n", (void*)elements);152153if (!NSK_JVMTI_VERIFY(jvmti->Allocate(*size, bytes))) {154nsk_jvmti_setFailStatus();155return NSK_FALSE;156}157NSK_DISPLAY1(" ... created bytes array: 0x%p\n", (void*)*bytes);158159for (i = 0; i < *size; i++) {160(*bytes)[i] = (unsigned char)elements[i];161}162NSK_DISPLAY1(" ... copied bytecode: %d bytes\n", (int)*size);163164NSK_DISPLAY1("Release elements list: 0x%p\n", (void*)elements);165NSK_TRACE(jni->ReleaseByteArrayElements(array, elements, JNI_ABORT));166NSK_DISPLAY0(" ... released\n");167168return NSK_TRUE;169}170171/* ============================================================================= */172173/** Agent algorithm. */174static void JNICALL175agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {176NSK_DISPLAY0("Wait for debuggee to become ready\n");177if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))178return;179180/* perform testing */181{182NSK_DISPLAY0(">>> Obtain original bytecode of tested class\n");183{184jclass debugeeClass = NULL;185186NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_CLASS_NAME);187if (!NSK_JNI_VERIFY(jni, (debugeeClass =188jni->FindClass(DEBUGEE_CLASS_NAME)) != NULL)) {189nsk_jvmti_setFailStatus();190return;191}192NSK_DISPLAY1(" ... found class: 0x%p\n", (void*)debugeeClass);193194if (!NSK_VERIFY(getBytecode(jvmti, jni, debugeeClass,195ORIG_BYTECODE_FIELD_NAME,196BYTECODE_FIELD_SIG,197&origClassSize, &origClassBytes)))198return;199}200201NSK_DISPLAY0(">>> Testcase #1: Load tested class and check CLASS_FILE_LOAD_HOOK event\n");202{203jvmtiEvent event = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;204205NSK_DISPLAY1("Enable event: %s\n", "CLASS_FILE_LOAD_HOOK");206if (!NSK_VERIFY(nsk_jvmti_enableEvents(JVMTI_ENABLE, 1, &event, NULL)))207return;208NSK_DISPLAY0(" ... event enabled\n");209210NSK_DISPLAY0("Let debugee to load tested class\n");211if (!NSK_VERIFY(nsk_jvmti_resumeSync()))212return;213NSK_DISPLAY0("Wait for tested class to be loaded\n");214if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))215return;216217NSK_DISPLAY1("Disable event: %s\n", "CLASS_FILE_LOAD_HOOK");218if (NSK_VERIFY(nsk_jvmti_enableEvents(JVMTI_DISABLE, 1, &event, NULL))) {219NSK_DISPLAY0(" ... event disabled\n");220}221222NSK_DISPLAY1("Check if event was received: %s\n", "CLASS_FILE_LOAD_HOOK");223if (eventsCount != 1) {224NSK_COMPLAIN3("Unexpected number of %s events for tested class:\n"225"# got events: %d\n"226"# expected: %d\n",227"CLASS_FILE_LOAD_HOOK",228eventsCount, 1);229nsk_jvmti_setFailStatus();230} else {231NSK_DISPLAY1(" ... received: %d events\n", eventsCount);232}233}234235NSK_DISPLAY0(">>> Clean used data\n");236{237NSK_DISPLAY1("Deallocate bytecode array: 0x%p\n", (void*)origClassBytes);238if (!NSK_JVMTI_VERIFY(jvmti->Deallocate(origClassBytes))) {239nsk_jvmti_setFailStatus();240}241}242}243244NSK_DISPLAY0("Let debugee to finish\n");245if (!NSK_VERIFY(nsk_jvmti_resumeSync()))246return;247}248249/* ============================================================================= */250251/** Callback for CLASS_FILE_LOAD_HOOK event **/252static void JNICALL253callbackClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *env,254jclass class_being_redefined,255jobject loader, const char* name, jobject protection_domain,256jint class_data_len, const unsigned char* class_data,257jint *new_class_data_len, unsigned char** new_class_data) {258259NSK_DISPLAY5(" <CLASS_FILE_LOAD_HOOK>: name: %s, loader: 0x%p, redefined: 0x%p, bytecode: 0x%p:%d\n",260nsk_null_string(name), (void*)loader, (void*)class_being_redefined,261(void*)class_data, (int)class_data_len);262263if (name != NULL && (strcmp(name, TESTED_CLASS_NAME) == 0)) {264NSK_DISPLAY1("SUCCESS! CLASS_FILE_LOAD_HOOK for tested class: %s\n", TESTED_CLASS_NAME);265eventsCount++;266267NSK_DISPLAY1("Check class_being_redefined: 0x%p\n", (void*)class_being_redefined);268if (class_being_redefined != NULL) {269NSK_COMPLAIN1("Unexpected not NULL class_being_redefined in CLASS_FILE_LOAD_HOOK: 0x%p\n",270(void*)class_being_redefined);271nsk_jvmti_setFailStatus();272}273274if (!checkBytecode("original", class_data_len, class_data,275origClassSize, origClassBytes, NSK_TRUE)) {276nsk_jvmti_setFailStatus();277}278}279}280281/* ============================================================================= */282283/** Agent library initialization. */284#ifdef STATIC_BUILD285JNIEXPORT jint JNICALL Agent_OnLoad_classfloadhk002(JavaVM *jvm, char *options, void *reserved) {286return Agent_Initialize(jvm, options, reserved);287}288JNIEXPORT jint JNICALL Agent_OnAttach_classfloadhk002(JavaVM *jvm, char *options, void *reserved) {289return Agent_Initialize(jvm, options, reserved);290}291JNIEXPORT jint JNI_OnLoad_classfloadhk002(JavaVM *jvm, char *options, void *reserved) {292return JNI_VERSION_1_8;293}294#endif295jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {296jvmtiEnv* jvmti = NULL;297298/* init framework and parse options */299if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))300return JNI_ERR;301302timeout = nsk_jvmti_getWaitTime() * 60 * 1000;303304/* create JVMTI environment */305if (!NSK_VERIFY((jvmti =306nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))307return JNI_ERR;308309NSK_DISPLAY1("Add required capability: %s\n", "can_generate_eraly_class_hook_events");310{311jvmtiCapabilities caps;312313memset(&caps, 0, sizeof(caps));314caps.can_generate_all_class_hook_events = 1;315if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {316return JNI_ERR;317}318}319NSK_DISPLAY0(" ... added\n");320321NSK_DISPLAY1("Set callback for event: %s\n", "CLASS_FILE_LOAD_HOOK");322{323jvmtiEventCallbacks callbacks;324jint size = (jint)sizeof(callbacks);325326memset(&callbacks, 0, sizeof(callbacks));327callbacks.ClassFileLoadHook = callbackClassFileLoadHook;328if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, size))) {329return JNI_ERR;330}331}332NSK_DISPLAY0(" ... set\n");333334/* register agent proc and arg */335if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))336return JNI_ERR;337338return JNI_OK;339}340341/* ============================================================================= */342343}344345346