Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c
41159 views
/*1* Copyright (c) 2016, 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 "jvmti.h"2627#ifdef __cplusplus28extern "C" {29#endif3031#ifndef JNI_ENV_ARG3233#ifdef __cplusplus34#define JNI_ENV_ARG(x, y) y35#define JNI_ENV_PTR(x) x36#else37#define JNI_ENV_ARG(x,y) x, y38#define JNI_ENV_PTR(x) (*x)39#endif4041#endif4243#define TranslateError(err) "JVMTI error"4445#define PASSED 046#define FAILED 24748static const char *EXPECTED_SIGNATURE = "Ljava/util/Collections;";49static const char *EXC_CNAME = "java/lang/Exception";5051static jvmtiEnv *jvmti = NULL;52static jint result = PASSED;53static jboolean printdump = JNI_FALSE;5455static jboolean with_early_vm_start_capability = JNI_FALSE;5657static jboolean class_in_class_load_events_vm_start = JNI_FALSE;58static jboolean class_in_class_load_events_vm_live = JNI_FALSE;59static jboolean class_in_class_prepare_events_vm_start = JNI_FALSE;60static jboolean class_in_class_prepare_events_vm_live = JNI_FALSE;6162static int class_load_events_vm_start_count = 0;63static int class_prepare_events_vm_start_count = 0;6465static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);6667JNIEXPORT68jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {69return Agent_Initialize(jvm, options, reserved);70}7172JNIEXPORT73jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {74return Agent_Initialize(jvm, options, reserved);75}7677JNIEXPORT78jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {79return JNI_VERSION_9;80}8182static83jint throw_exc(JNIEnv *env, char *msg) {84jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME));8586if (exc_class == NULL) {87printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME);88return -1;89}90return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg);91}9293static void JNICALL94Callback_ClassFileLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {95jvmtiPhase phase;96char *sig, *generic;97jvmtiError err;9899err = (*jvmti)->GetPhase(jvmti_env,&phase);100if (err != JVMTI_ERROR_NONE) {101printf("ClassLoad event: GetPhase error: %s (%d)\n", TranslateError(err), err);102result = FAILED;103return;104}105106if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) {107108err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic);109110if (err != JVMTI_ERROR_NONE) {111printf("ClassLoad event: GetClassSignature error: %s (%d)\n", TranslateError(err), err);112result = FAILED;113return;114}115116if (phase == JVMTI_PHASE_START) {117class_load_events_vm_start_count++;118if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {119class_in_class_load_events_vm_start = JNI_TRUE;120}121} else {122if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {123class_in_class_load_events_vm_live = JNI_TRUE;124}125}126127if (printdump == JNI_TRUE) {128printf(">>> ClassLoad event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig);129}130} else {131printf("ClassLoad event: get event in unexpected phase(%d)\n", phase);132result = FAILED;133}134}135136static void JNICALL137Callback_ClassFilePrepare(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {138jvmtiPhase phase;139char *sig, *generic;140jvmtiError err;141142err = (*jvmti)->GetPhase(jvmti_env,&phase);143if (err != JVMTI_ERROR_NONE) {144printf("ClassPrepare event: GetPhase error: %s (%d)\n", TranslateError(err), err);145result = FAILED;146return;147}148149if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) {150151err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic);152153if (err != JVMTI_ERROR_NONE) {154printf("ClassPrepare event: GetClassSignature error: %s (%d)\n", TranslateError(err), err);155result = FAILED;156return;157}158159if (phase == JVMTI_PHASE_START) {160class_prepare_events_vm_start_count++;161if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {162class_in_class_prepare_events_vm_start = JNI_TRUE;163}164} else {165if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {166class_in_class_prepare_events_vm_live = JNI_TRUE;167}168}169170if (printdump == JNI_TRUE) {171printf(">>> ClassPrepare event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig);172}173} else {174printf("ClassPrepare event: get event in unexpected phase(%d)\n", phase);175result = FAILED;176}177}178179static180jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {181jint res, size;182jvmtiCapabilities caps;183jvmtiEventCallbacks callbacks;184jvmtiError err;185186if (options != NULL) {187if (strstr(options, "with_early_vmstart") != NULL) {188with_early_vm_start_capability = JNI_TRUE;189}190if (strstr(options, "printdump") != NULL) {191printdump = JNI_TRUE;192}193}194195res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),196JVMTI_VERSION_9);197if (res != JNI_OK || jvmti == NULL) {198printf(" Error: wrong result of a valid call to GetEnv!\n");199return JNI_ERR;200}201202if (with_early_vm_start_capability == JNI_TRUE) {203printf("Enabling following capability: can_generate_early_vmstart\n");204memset(&caps, 0, sizeof(caps));205caps.can_generate_early_vmstart = 1;206207err = (*jvmti)->AddCapabilities(jvmti, &caps);208if (err != JVMTI_ERROR_NONE) {209printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err);210return JNI_ERR;211}212}213214size = (jint)sizeof(callbacks);215216memset(&callbacks, 0, sizeof(callbacks));217callbacks.ClassLoad = Callback_ClassFileLoad;218callbacks.ClassPrepare = Callback_ClassFilePrepare;219220err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);221if (err != JVMTI_ERROR_NONE) {222printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err);223return JNI_ERR;224}225226err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL);227if (err != JVMTI_ERROR_NONE) {228printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);229return JNI_ERR;230}231232err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);233234if (err != JVMTI_ERROR_NONE) {235printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);236return JNI_ERR;237}238239return JNI_OK;240}241242JNIEXPORT jint JNICALL243Java_MAAClassLoadPrepare_check(JNIEnv *env, jclass cls) {244jobject loader = NULL;245246if (jvmti == NULL) {247throw_exc(env, "JVMTI client was not properly loaded!\n");248return FAILED;249}250251if (with_early_vm_start_capability == JNI_TRUE) {252/*253* Expecting that "java/util/Collections" class from java.base module is present in the254* ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart255* capability is enabled.256* Expecting that ClassLoad and ClassPrepare events are sent in the VM early start phase257* when can_generate_early_vmstart is enabled(JDK-8165681).258*/259if (class_load_events_vm_start_count == 0) {260throw_exc(env, "Didn't get ClassLoad events in start phase!\n");261return FAILED;262}263264printf("Expecting to find '%s' class in ClassLoad events during VM early start phase.\n", EXPECTED_SIGNATURE);265if (class_in_class_load_events_vm_start == JNI_FALSE) {266throw_exc(env, "Unable to find expected class in ClassLoad events during early start phase!\n");267return FAILED;268}269270if (class_prepare_events_vm_start_count == 0) {271throw_exc(env, "Didn't get ClassPrepare events in start phase!\n");272return FAILED;273}274275printf("Expecting to find '%s' class in ClassPrepare events during VM early start phase.\n", EXPECTED_SIGNATURE);276if (class_in_class_prepare_events_vm_start == JNI_FALSE) {277throw_exc(env, "Unable to find expected class in ClassPrepare events during early start phase!\n");278return FAILED;279}280} else {281/*282* Expecting that "java/util/Collections" class from java.base module is not present in the283* ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart284* capability is disabled.285*/286printf("Expecting that '%s' class is absent in ClassLoad events during normal VM start phase.\n", EXPECTED_SIGNATURE);287if (class_in_class_prepare_events_vm_start == JNI_TRUE) {288throw_exc(env, "Class is found in ClassLoad events during normal VM start phase!\n");289return FAILED;290}291292printf("Expecting that '%s' class is absent in ClassPrepare events during normal VM start phase.\n", EXPECTED_SIGNATURE);293if (class_in_class_prepare_events_vm_start == JNI_TRUE) {294throw_exc(env, "Class is found in ClassPrepare events during normal VM start phase!\n");295return FAILED;296}297}298299/*300* In any case, we not expect to see "java/util/Collections" class from java.base module301* in the ClassLoad and ClassPrepare events during VM Live phase.302*/303if (class_in_class_prepare_events_vm_live == JNI_TRUE) {304throw_exc(env, "Class is found in ClassLoad events during VM Live phase!\n");305return FAILED;306}307308if (class_in_class_prepare_events_vm_live == JNI_TRUE) {309throw_exc(env, "Class is found in ClassPrepare events during VM Live phase!\n");310return FAILED;311}312313return result;314}315316#ifdef __cplusplus317}318#endif319320321