1 /*
2 * Copyright (c) 2004, 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 <string.h>
25 #include "jvmti.h"
26 #include "agent_common.h"
27 #include "jni_tools.h"
28 #include "jvmti_tools.h"
29 #include "JVMTITools.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /* ============================================================================= */
36
37 /* scaffold objects */
38 static JNIEnv* jni = NULL;
39 static jvmtiEnv *jvmti = NULL;
40 static jlong timeout = 0;
41 static jrawMonitorID syncLock = NULL;
42
43 /* constant names */
44 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1)
45 #define EXPECTED_CLASS_NAME "nsk.jvmti.scenarios.events.EM06.em06t001a"
46 #define CLASS_LOADER_COUNT_PARAM "classLoaderCount"
47
48 static int classLoaderCount = 0;
49 static int classloadEventCount = 0;
50 static int classprepareEventCount = 0;
51
52 /* ============================================================================= */
53
54 /* callbacks */
55
56 void
handler(jvmtiEvent event,jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread,jclass klass)57 handler(jvmtiEvent event, jvmtiEnv* jvmti, JNIEnv* jni_env,
58 jthread thread, jclass klass) {
59
60 jmethodID methodID;
61 jclass classObject;
62 jstring jclassName;
63 const char *className;
64
65 if (!NSK_JNI_VERIFY(jni_env, (classObject =
66 NSK_CPP_STUB2(GetObjectClass, jni_env, klass)) != NULL)) {
67 nsk_jvmti_setFailStatus();
68 return;
69 }
70
71 if (!NSK_JNI_VERIFY(jni_env, (methodID =
72 NSK_CPP_STUB4(GetMethodID, jni_env, classObject,
73 "getName", "()Ljava/lang/String;")) != NULL)) {
74 nsk_jvmti_setFailStatus();
75 return;
76 }
77
78 jclassName = NSK_CPP_STUB3(CallObjectMethod, jni_env, klass,
79 methodID);
80
81 className = NSK_CPP_STUB3(GetStringUTFChars, jni_env, jclassName, 0);
82
83 if ( className != NULL && (strcmp(className, EXPECTED_CLASS_NAME)==0) ) {
84
85 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, syncLock)))
86 nsk_jvmti_setFailStatus();
87
88 switch (event) {
89 case JVMTI_EVENT_CLASS_LOAD:
90 classloadEventCount++; break;
91 case JVMTI_EVENT_CLASS_PREPARE:
92 classprepareEventCount++; break;
93 default:
94 NSK_COMPLAIN1("Unexpected event %s", TranslateEvent(event));
95 nsk_jvmti_setFailStatus();
96 }
97
98 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, syncLock)))
99 nsk_jvmti_setFailStatus();
100
101 }
102
103 NSK_CPP_STUB3(ReleaseStringUTFChars, jni_env, jclassName, className);
104 }
105
106 JNIEXPORT void JNICALL
cbClassLoad(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread,jclass klass)107 cbClassLoad(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread, jclass klass) {
108
109 handler(JVMTI_EVENT_CLASS_LOAD, jvmti, jni_env, thread, klass);
110 }
111
112 JNIEXPORT void JNICALL
cbClassPrepare(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread,jclass klass)113 cbClassPrepare(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread, jclass klass) {
114
115 handler(JVMTI_EVENT_CLASS_PREPARE, jvmti, jni_env, thread, klass);
116 }
117
118 /* ============================================================================= */
119
120 static int
enableEvent(jvmtiEventMode enable,jvmtiEvent event)121 enableEvent(jvmtiEventMode enable, jvmtiEvent event) {
122 if (!NSK_JVMTI_VERIFY(
123 NSK_CPP_STUB4(SetEventNotificationMode, jvmti, enable,
124 event, NULL))) {
125 nsk_jvmti_setFailStatus();
126 return NSK_FALSE;
127 }
128
129 return NSK_TRUE;
130 }
131
132 /* ============================================================================= */
133
134 /**
135 * Testcase: check tested events.
136 * - check if expected events received for each method
137 *
138 * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break.
139 */
checkEvents()140 int checkEvents() {
141
142 int result = NSK_TRUE;
143
144 if (classloadEventCount == classLoaderCount) {
145 NSK_DISPLAY1("Expected number of JVMTI_EVENT_CLASS_LOAD events %d\n",
146 classloadEventCount);
147 } else {
148 NSK_COMPLAIN2("Unexpected number of JVMTI_EVENT_CLASS_LOAD events %d\n\texpected value %d\n",
149 classloadEventCount,
150 classLoaderCount);
151 result = NSK_FALSE;
152 }
153
154 if (classprepareEventCount == classLoaderCount) {
155 NSK_DISPLAY1("Expected number of JVMTI_EVENT_CLASS_PREPARE events %d\n",
156 classloadEventCount);
157 } else {
158 NSK_COMPLAIN2("Unexpected number of JVMTI_EVENT_CLASS_PREPARE events %d\n\texpected value %d\n",
159 classprepareEventCount,
160 classLoaderCount);
161 result = NSK_FALSE;
162 }
163
164 return result;
165 }
166
167 /* ============================================================================= */
168
169 static int
setCallBacks()170 setCallBacks() {
171 jvmtiEventCallbacks eventCallbacks;
172 memset(&eventCallbacks, 0, sizeof(eventCallbacks));
173
174 eventCallbacks.ClassLoad = cbClassLoad;
175 eventCallbacks.ClassPrepare = cbClassPrepare;
176
177 if (!NSK_JVMTI_VERIFY(
178 NSK_CPP_STUB3(SetEventCallbacks, jvmti,
179 &eventCallbacks,
180 sizeof(eventCallbacks))))
181 return NSK_FALSE;
182
183 return NSK_TRUE;
184 }
185
186 /* ============================================================================= */
187
188 /** Agent algorithm. */
189 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * agentJNI,void * arg)190 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
191
192 if (!NSK_JVMTI_VERIFY(
193 NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_syncLock", &syncLock))) {
194 nsk_jvmti_setFailStatus();
195 return;
196 }
197
198 jni = agentJNI;
199
200 NSK_DISPLAY0("Wait for debuggee to become ready\n");
201 if (!nsk_jvmti_waitForSync(timeout))
202 return;
203
204 if (!setCallBacks()) {
205 return;
206 }
207
208 if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD)
209 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE)) {
210 NSK_COMPLAIN0("Events could not be enabled");
211 nsk_jvmti_setFailStatus();
212 return;
213 }
214
215 NSK_DISPLAY0("Let debuggee to load class\n");
216 if (!nsk_jvmti_resumeSync())
217 return;
218
219 if (!nsk_jvmti_waitForSync(timeout))
220 return;
221
222 if (!checkEvents()) {
223 nsk_jvmti_setFailStatus();
224 }
225
226 if (!enableEvent(JVMTI_DISABLE, JVMTI_EVENT_CLASS_LOAD)
227 || !enableEvent(JVMTI_DISABLE, JVMTI_EVENT_CLASS_PREPARE)) {
228 NSK_COMPLAIN0("Events could not be disabled");
229 nsk_jvmti_setFailStatus();
230 }
231
232 NSK_DISPLAY0("Let debuggee to finish\n");
233 if (!nsk_jvmti_resumeSync())
234 return;
235
236 if (!NSK_JVMTI_VERIFY(
237 NSK_CPP_STUB2(DestroyRawMonitor, jvmti, syncLock)))
238 nsk_jvmti_setFailStatus();
239
240 }
241
242 /* ============================================================================= */
243
244 /** Agent library initialization. */
245 #ifdef STATIC_BUILD
Agent_OnLoad_em06t001(JavaVM * jvm,char * options,void * reserved)246 JNIEXPORT jint JNICALL Agent_OnLoad_em06t001(JavaVM *jvm, char *options, void *reserved) {
247 return Agent_Initialize(jvm, options, reserved);
248 }
Agent_OnAttach_em06t001(JavaVM * jvm,char * options,void * reserved)249 JNIEXPORT jint JNICALL Agent_OnAttach_em06t001(JavaVM *jvm, char *options, void *reserved) {
250 return Agent_Initialize(jvm, options, reserved);
251 }
JNI_OnLoad_em06t001(JavaVM * jvm,char * options,void * reserved)252 JNIEXPORT jint JNI_OnLoad_em06t001(JavaVM *jvm, char *options, void *reserved) {
253 return JNI_VERSION_1_8;
254 }
255 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)256 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
257
258 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
259 return JNI_ERR;
260
261 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
262 classLoaderCount = nsk_jvmti_findOptionIntValue(CLASS_LOADER_COUNT_PARAM, 100);
263
264 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
265 return JNI_ERR;
266
267 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
268 return JNI_ERR;
269
270 return JNI_OK;
271 }
272
273 /* ============================================================================= */
274
275
276 #ifdef __cplusplus
277 }
278 #endif
279