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 extern "C" {
32
33 /* ============================================================================= */
34
35 /* scaffold objects */
36 static jlong timeout = 0;
37 static jvmtiEnv *jvmti = NULL;
38 static jrawMonitorID syncLock = NULL;
39
40 /* constant names */
41 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1)
42 #define EXPECTED_COUNT 0
43
44 static int eventCount[JVMTI_EVENT_COUNT];
45
46 /* ============================================================================= */
47
showEventStatistics()48 void showEventStatistics() {
49 int i;
50 const char* str;
51
52 NSK_DISPLAY0("\n");
53 NSK_DISPLAY0("Event statistics\n");
54 NSK_DISPLAY0("----------------\n");
55 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
56 if (eventCount[i] > 0) {
57 str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL));
58 NSK_DISPLAY2("%-40s %7d\n", str, eventCount[i]);
59 }
60 }
61 }
62
63 /* ========================================================================== */
64
changeCount(jvmtiEvent event)65 void changeCount(jvmtiEvent event) {
66
67 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(syncLock)))
68 nsk_jvmti_setFailStatus();
69
70 eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL]++;
71
72 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(syncLock)))
73 nsk_jvmti_setFailStatus();
74
75 }
76
77 /* ============================================================================= */
78
79 /* callbacks */
80 JNIEXPORT void JNICALL
cbVMInit(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread)81 cbVMInit(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread) {
82 changeCount(JVMTI_EVENT_VM_INIT);
83 NSK_DISPLAY0("--->VMINit is received\n");
84 }
85
86 JNIEXPORT void JNICALL
cbVMDeath(jvmtiEnv * jvmti,JNIEnv * jni_env)87 cbVMDeath(jvmtiEnv* jvmti, JNIEnv* jni_env) {
88 changeCount(JVMTI_EVENT_VM_DEATH);
89
90 if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock)))
91 nsk_jvmti_setFailStatus();
92
93 }
94
95 void JNICALL
cbException(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jobject exception,jmethodID catch_method,jlocation catch_location)96 cbException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
97 jmethodID method, jlocation location, jobject exception,
98 jmethodID catch_method, jlocation catch_location) {
99 changeCount(JVMTI_EVENT_EXCEPTION);
100 }
101
102 void JNICALL
cbExceptionCatch(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jobject exception)103 cbExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
104 jmethodID method, jlocation location, jobject exception) {
105 changeCount(JVMTI_EVENT_EXCEPTION_CATCH);
106 }
107
108 void JNICALL
cbSingleStep(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location)109 cbSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
110 jmethodID method, jlocation location) {
111 changeCount(JVMTI_EVENT_SINGLE_STEP);
112 }
113
114 void JNICALL
cbFramePop(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jboolean was_popped_by_exception)115 cbFramePop(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
116 jmethodID method, jboolean was_popped_by_exception) {
117 changeCount(JVMTI_EVENT_FRAME_POP);
118 }
119
120 void JNICALL
cbBreakpoint(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location)121 cbBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
122 jmethodID method, jlocation location) {
123 changeCount(JVMTI_EVENT_BREAKPOINT);
124 }
125
126 void JNICALL
cbFieldAccess(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field)127 cbFieldAccess(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
128 jmethodID method, jlocation location, jclass field_klass,
129 jobject object, jfieldID field) {
130 changeCount(JVMTI_EVENT_FIELD_ACCESS);
131 }
132
133 void JNICALL
cbFieldModification(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field,char signature_type,jvalue new_value)134 cbFieldModification(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
135 jmethodID method, jlocation location, jclass field_klass,
136 jobject object, jfieldID field, char signature_type,
137 jvalue new_value) {
138 changeCount(JVMTI_EVENT_FIELD_MODIFICATION);
139 }
140
141 void JNICALL
cbMethodEntry(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method)142 cbMethodEntry(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
143 jmethodID method) {
144 changeCount(JVMTI_EVENT_METHOD_ENTRY);
145 }
146
147 void JNICALL
cbMethodExit(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,jboolean was_popped_by_exception,jvalue return_value)148 cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
149 jmethodID method, jboolean was_popped_by_exception,
150 jvalue return_value) {
151 changeCount(JVMTI_EVENT_METHOD_EXIT);
152 }
153
154 void JNICALL
cbNativeMethodBind(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jmethodID method,void * address,void ** new_address_ptr)155 cbNativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env,jthread thread,
156 jmethodID method, void* address, void** new_address_ptr) {
157 changeCount(JVMTI_EVENT_NATIVE_METHOD_BIND);
158 }
159
160 void JNICALL
cbCompiledMethodLoad(jvmtiEnv * jvmti_env,jmethodID method,jint code_size,const void * code_addr,jint map_length,const jvmtiAddrLocationMap * map,const void * compile_info)161 cbCompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size,
162 const void* code_addr, jint map_length,
163 const jvmtiAddrLocationMap* map, const void* compile_info) {
164 changeCount(JVMTI_EVENT_COMPILED_METHOD_LOAD);
165 }
166
167 void JNICALL
cbCompiledMethodUnload(jvmtiEnv * jvmti_env,jmethodID method,const void * code_addr)168 cbCompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method,
169 const void* code_addr) {
170 changeCount(JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
171 }
172
173 void JNICALL
cbMonitorWait(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jlong tout)174 cbMonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
175 jobject object, jlong tout) {
176
177 changeCount(JVMTI_EVENT_MONITOR_WAIT);
178 }
179
180 void JNICALL
cbMonitorWaited(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jboolean timed_out)181 cbMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
182 jobject object, jboolean timed_out) {
183
184 changeCount(JVMTI_EVENT_MONITOR_WAITED);
185 }
186
187 JNIEXPORT void JNICALL
cbMonitorContendedEnter(jvmtiEnv * jvmti,JNIEnv * jni_env,jthread thread,jobject object)188 cbMonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread,
189 jobject object) {
190
191 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
192 }
193
194 void JNICALL
cbMonitorContendedEntered(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object)195 cbMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
196 jobject object) {
197
198 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
199 }
200
201 void JNICALL
cbGarbageCollectionStart(jvmtiEnv * jvmti_env)202 cbGarbageCollectionStart(jvmtiEnv *jvmti_env) {
203 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_START);
204 }
205
206 void JNICALL
cbGarbageCollectionFinish(jvmtiEnv * jvmti_env)207 cbGarbageCollectionFinish(jvmtiEnv *jvmti_env) {
208 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
209 }
210
211 void JNICALL
cbObjectFree(jvmtiEnv * jvmti_env,jlong tag)212 cbObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
213 changeCount(JVMTI_EVENT_OBJECT_FREE);
214 }
215
216 void JNICALL
cbVMObjectAlloc(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,jobject object,jclass object_klass,jlong size)217 cbVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
218 jobject object, jclass object_klass, jlong size) {
219
220 changeCount(JVMTI_EVENT_VM_OBJECT_ALLOC);
221 }
222
223 /* ============================================================================= */
224
enableOptionalEvents(jvmtiEnv * jvmti)225 int enableOptionalEvents(jvmtiEnv *jvmti) {
226 int i;
227 int result = NSK_TRUE;
228
229 NSK_DISPLAY0("Enable events\n");
230
231 /* enabling optional events */
232 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
233 jvmtiEvent event = (jvmtiEvent)(i + JVMTI_MIN_EVENT_TYPE_VAL);
234 if (nsk_jvmti_isOptionalEvent(event))
235 if (!NSK_JVMTI_VERIFY_CODE(JVMTI_ERROR_MUST_POSSESS_CAPABILITY,
236 jvmti->SetEventNotificationMode(JVMTI_ENABLE, event, NULL))) {
237 NSK_COMPLAIN1("Unexpected error enabling %s\n",
238 TranslateEvent(event));
239 result = NSK_FALSE;
240 }
241 }
242
243 return result;
244 }
245
246 /* ============================================================================= */
247
248 /**
249 * Testcase: check tested events.
250 * - check if expected events received for each method
251 *
252 * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break.
253 */
checkEvents()254 int checkEvents() {
255 int i;
256 jvmtiEvent event;
257 int result = NSK_TRUE;
258
259 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
260
261 event = (jvmtiEvent) (i + JVMTI_MIN_EVENT_TYPE_VAL);
262
263 if (nsk_jvmti_isOptionalEvent(event) && eventCount[i] > EXPECTED_COUNT) {
264 nsk_jvmti_setFailStatus();
265 NSK_COMPLAIN3("Unexpected number of %s events:\n\treceived: %7d\n\texpected: %7d\n",
266 TranslateEvent(event),
267 eventCount[i],
268 EXPECTED_COUNT);
269 result = NSK_FALSE;
270 }
271 }
272
273 return result;
274 }
275
276 /* ============================================================================= */
277
setCallBacks(jvmtiEnv * jvmti)278 static int setCallBacks(jvmtiEnv *jvmti) {
279 int i;
280
281 jvmtiEventCallbacks eventCallbacks;
282 memset(&eventCallbacks, 0, sizeof(eventCallbacks));
283
284 for (i = 0; i < JVMTI_EVENT_COUNT; i++) {
285 eventCount[i] = 0;
286 }
287
288 eventCallbacks.VMInit = cbVMInit;
289 eventCallbacks.VMDeath = cbVMDeath;
290 eventCallbacks.Exception = cbException;
291 eventCallbacks.ExceptionCatch = cbExceptionCatch;
292 eventCallbacks.SingleStep = cbSingleStep;
293 eventCallbacks.FramePop = cbFramePop;
294 eventCallbacks.Breakpoint = cbBreakpoint;
295 eventCallbacks.FieldAccess = cbFieldAccess;
296 eventCallbacks.FieldModification = cbFieldModification;
297 eventCallbacks.MethodEntry = cbMethodEntry;
298 eventCallbacks.MethodExit = cbMethodExit;
299 eventCallbacks.NativeMethodBind = cbNativeMethodBind;
300 eventCallbacks.CompiledMethodLoad = cbCompiledMethodLoad;
301 eventCallbacks.MonitorWait = cbMonitorWait;
302 eventCallbacks.MonitorWaited = cbMonitorWaited;
303 eventCallbacks.MonitorContendedEnter = cbMonitorContendedEnter;
304 eventCallbacks.MonitorContendedEntered = cbMonitorContendedEntered;
305 eventCallbacks.GarbageCollectionStart = cbGarbageCollectionStart;
306 eventCallbacks.GarbageCollectionFinish = cbGarbageCollectionFinish;
307 eventCallbacks.ObjectFree = cbObjectFree;
308 eventCallbacks.VMObjectAlloc = cbVMObjectAlloc;
309
310 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks))))
311 return NSK_FALSE;
312
313 return NSK_TRUE;
314 }
315
316 /* ============================================================================= */
317
318 /** Agent algorithm. */
319 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * agentJNI,void * arg)320 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
321
322 NSK_DISPLAY0("Wait for debuggee to become ready\n");
323 if (!nsk_jvmti_waitForSync(timeout))
324 return;
325
326 if (!checkEvents()) {
327 nsk_jvmti_setFailStatus();
328 }
329 showEventStatistics();
330
331 NSK_DISPLAY0("Let debuggee to finish\n");
332 if (!nsk_jvmti_resumeSync())
333 return;
334
335 }
336
337 /* ============================================================================= */
338
339 /** Agent library initialization. */
340 #ifdef STATIC_BUILD
Agent_OnLoad_em07t001(JavaVM * jvm,char * options,void * reserved)341 JNIEXPORT jint JNICALL Agent_OnLoad_em07t001(JavaVM *jvm, char *options, void *reserved) {
342 return Agent_Initialize(jvm, options, reserved);
343 }
Agent_OnAttach_em07t001(JavaVM * jvm,char * options,void * reserved)344 JNIEXPORT jint JNICALL Agent_OnAttach_em07t001(JavaVM *jvm, char *options, void *reserved) {
345 return Agent_Initialize(jvm, options, reserved);
346 }
JNI_OnLoad_em07t001(JavaVM * jvm,char * options,void * reserved)347 JNIEXPORT jint JNI_OnLoad_em07t001(JavaVM *jvm, char *options, void *reserved) {
348 return JNI_VERSION_1_8;
349 }
350 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)351 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
352
353 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
354 return JNI_ERR;
355
356 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
357
358 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
359 return JNI_ERR;
360
361 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_syncLock", &syncLock))) {
362 nsk_jvmti_setFailStatus();
363 return JNI_ERR;
364 }
365
366 if (!setCallBacks(jvmti)) {
367 return JNI_ERR;
368 }
369
370 nsk_jvmti_showPossessedCapabilities(jvmti);
371
372 if (!enableOptionalEvents(jvmti)) {
373 return JNI_ERR;
374 }
375
376 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
377 return JNI_ERR;
378
379 return JNI_OK;
380 }
381
382 /* ============================================================================= */
383
384
385 }
386