1 /*
2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include "jvmti.h"
27 #include "agent_common.h"
28 
29 #define PASSED 0
30 #define STATUS_FAILED 2
31 
32 static jvmtiEnv *jvmti;
33 static jint result = PASSED;
34 
35 /*
36  * Class:     nsk.jvmti.unit.extmech
37  * Method:    isClassUnloadingEnabled
38  * Signature: ()Z
39  */
40 JNIEXPORT jboolean JNICALL
Java_nsk_jvmti_unit_extmech_isClassUnloadingEnabled(JNIEnv * env,jclass cls)41 Java_nsk_jvmti_unit_extmech_isClassUnloadingEnabled
42   (JNIEnv *env, jclass cls)
43 {
44     jint count, i;
45     jvmtiExtensionFunctionInfo* ext_funcs;
46     jvmtiError err;
47 
48     err = (*jvmti)->GetExtensionFunctions(jvmti, &count, &ext_funcs);
49     if (err != JVMTI_ERROR_NONE) {
50         fprintf(stderr, "GetExtensionFunctions failed: %d\n", err);
51         result = STATUS_FAILED;
52         return JNI_FALSE;
53     }
54 
55     for (i=0; i<count; i++) {
56         if (strcmp(ext_funcs[i].id, (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled") == 0) {
57             jboolean enabled;
58             err = (*ext_funcs[i].func)(jvmti, &enabled);
59 
60             if (err != JVMTI_ERROR_NONE) {
61                 fprintf(stderr, "IsClassUnloadingEnabled failed: %d\n", err);
62                 result = STATUS_FAILED;
63                 return JNI_FALSE;
64             } else {
65                 return enabled;
66             }
67         }
68     }
69 
70     return JNI_FALSE;
71 }
72 
73 static void JNICALL
ClassUnload(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jclass cls)74 ClassUnload(jvmtiEnv* jvmti_env, JNIEnv *jni_env, jthread thread, jclass cls) {
75 }
76 
77 /*
78  * Class:     nsk.jvmti.unit.extmech
79  * Method:    enableClassUnloadEvent
80  * Signature: (Z)V
81  */
82 JNIEXPORT void JNICALL
Java_nsk_jvmti_unit_extmech_enableClassUnloadEvent(JNIEnv * env,jclass cls,jboolean enable)83 Java_nsk_jvmti_unit_extmech_enableClassUnloadEvent
84   (JNIEnv *env, jclass cls, jboolean enable)
85 {
86     jint count, i;
87     jvmtiExtensionEventInfo* ext_events;
88     jvmtiError err;
89 
90     err = (*jvmti)->GetExtensionEvents(jvmti, &count, &ext_events);
91     if (err != JVMTI_ERROR_NONE) {
92         fprintf(stderr, "GetExtensionEvents failed: %d\n", err);
93         result = STATUS_FAILED;
94         return;
95     }
96 
97     for (i=0; i<count; i++) {
98         if (strcmp(ext_events[i].id, (char*)"com.sun.hotspot.events.ClassUnload") == 0) {
99 
100             err = (*jvmti)->SetExtensionEventCallback(jvmti, ext_events[i].extension_event_index,
101                 enable ? (jvmtiExtensionEvent)ClassUnload : NULL);
102 
103             if (err != JVMTI_ERROR_NONE) {
104                 fprintf(stderr, "SetExtenionEventCallback failed: %d\n", err);
105                 result = STATUS_FAILED;
106             } else {
107                 char* id = ext_events[i].id;
108                 if (enable) {
109                     fprintf(stderr, "%s callback enabled\n", id);
110                 } else {
111                     fprintf(stderr, "%s callback disabled\n", id);
112                 }
113             }
114             return;
115         }
116     }
117 }
118 
119 /*
120  * Class:     nsk.jvmti.unit.extmech
121  * Method:    dumpExtensions
122  * Signature: ()V
123  */
124 JNIEXPORT void JNICALL
Java_nsk_jvmti_unit_extmech_dumpExtensions(JNIEnv * env,jclass cls)125 Java_nsk_jvmti_unit_extmech_dumpExtensions
126   (JNIEnv *env, jclass cls)
127 {
128     jint count, i, j;
129     jvmtiExtensionFunctionInfo* ext_funcs;
130     jvmtiExtensionEventInfo* ext_events;
131     jvmtiError err;
132 
133     err = (*jvmti)->GetExtensionFunctions(jvmti, &count, &ext_funcs);
134     if (err != JVMTI_ERROR_NONE) {
135         fprintf(stderr, "GetExtensionFunctions failed: %d\n", err);
136         result = STATUS_FAILED;
137         return;
138     }
139 
140     fprintf(stderr, "Extension functions:\n");
141     for (i=0; i<count; i++) {
142         jvmtiParamInfo* params = ext_funcs[i].params;
143         jvmtiError* errors = ext_funcs[i].errors;
144 
145         fprintf(stderr, "%s (%s)\n", ext_funcs[i].id, ext_funcs[i].short_description);
146 
147         fprintf(stderr, "    Parameters:\n");
148 
149         for (j=0; j<ext_funcs[i].param_count; j++) {
150             fprintf(stderr, "      %s type:%d\n", params[j].name, params[j].base_type);
151         }
152 
153         fprintf(stderr, "    Errors:\n");
154         for (j=0; j<ext_funcs[i].error_count; j++) {
155             fprintf(stderr, "      %d\n", errors[j]);
156         }
157     }
158 
159     /* --- */
160 
161     err = (*jvmti)->GetExtensionEvents(jvmti, &count, &ext_events);
162     if (err != JVMTI_ERROR_NONE) {
163         fprintf(stderr, "GetExtensionEvents failed: %d\n", err);
164         result = STATUS_FAILED;
165         return;
166     }
167 
168     fprintf(stderr, "Extension events:\n");
169     for (i=0; i<count; i++) {
170         jvmtiParamInfo* params = ext_events[i].params;
171 
172         fprintf(stderr, "event: %d, %s (%s)\n",
173             ext_events[i].extension_event_index,
174             ext_events[i].id, ext_events[i].short_description);
175 
176         fprintf(stderr, "    Parameters:\n");
177 
178         for (j=0; j<ext_events[i].param_count; j++) {
179             fprintf(stderr, "      %s type:%d\n", params[j].name, params[j].base_type);
180         }
181 
182     }
183 }
184 
185 /*
186  * Class:     nsk.jvmti.unit.extmech
187  * Method:    getResult
188  * Signature: ()I
189  */
190 JNIEXPORT jint JNICALL
Java_nsk_jvmti_unit_extmech_getResult(JNIEnv * env,jclass cls)191 Java_nsk_jvmti_unit_extmech_getResult
192   (JNIEnv *env, jclass cls)
193 {
194     return result;
195 }
196 
197 /*
198  * JVM_OnLoad - add capabilities and enables OBJECT_FREE event
199  */
200 #ifdef STATIC_BUILD
Agent_OnLoad_extmech(JavaVM * jvm,char * options,void * reserved)201 JNIEXPORT jint JNICALL Agent_OnLoad_extmech(JavaVM *jvm, char *options, void *reserved) {
202     return Agent_Initialize(jvm, options, reserved);
203 }
Agent_OnAttach_extmech(JavaVM * jvm,char * options,void * reserved)204 JNIEXPORT jint JNICALL Agent_OnAttach_extmech(JavaVM *jvm, char *options, void *reserved) {
205     return Agent_Initialize(jvm, options, reserved);
206 }
JNI_OnLoad_extmech(JavaVM * jvm,char * options,void * reserved)207 JNIEXPORT jint JNI_OnLoad_extmech(JavaVM *jvm, char *options, void *reserved) {
208     return JNI_VERSION_1_8;
209 }
210 #endif
Agent_Initialize(JavaVM * vm,char * options,void * reserved)211 jint Agent_Initialize(JavaVM *vm, char *options, void *reserved)
212 {
213     jint rc;
214 
215     /* get JVMTI environment */
216 
217     rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_1);
218     if (rc != JNI_OK) {
219         fprintf(stderr, "Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
220         return JNI_ERR;
221     }
222 
223     return JNI_OK;
224 }
225