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 <stdlib.h>
25 #include <string.h>
26 #include "jni_tools.h"
27 #include "agent_common.h"
28 #include "jvmti_tools.h"
29 
30 #define PASSED 0
31 #define STATUS_FAILED 2
32 #define SAMPLE_TAG ((jlong) 111111)
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /* ========================================================================== */
39 
40 /* scaffold objects */
41 static jlong timeout = 0;
42 
43 /* test objects */
44 static jobject testedObject = NULL;
45 static jobject testedInstance = NULL;
46 static jclass testedClass = NULL;
47 static int ObjectsCount = 0;
48 
49 /* ========================================================================== */
50 
51 /** callback functions **/
52 
heap_object_callback(jlong class_tag,jlong size,jlong * tag_ptr,void * user_data)53 static jvmtiIterationControl JNICALL heap_object_callback
54     (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data)
55 {
56     char buffer[32];
57 
58     if (*tag_ptr != 0) {
59         NSK_DISPLAY1("tag = %s\n", jlong_to_string(*tag_ptr, buffer));
60         if (*tag_ptr == SAMPLE_TAG) {
61             ObjectsCount++;
62         } else {
63             NSK_COMPLAIN1("testedObject tagged incorrectly, expected=%s,",
64                 jlong_to_string(SAMPLE_TAG, buffer));
65             NSK_COMPLAIN1(" got=%s\n", jlong_to_string(*tag_ptr, buffer));
66             nsk_jvmti_setFailStatus();
67         }
68     }
69 
70     return JVMTI_ITERATION_CONTINUE;
71 }
72 
73 /* ========================================================================== */
74 
prepare(JNIEnv * jni)75 static int prepare(JNIEnv* jni) {
76     const char* CLASS_NAME = "nsk/jvmti/scenarios/multienv/MA04/ma04t002";
77     const char* FIELD_NAME = "testedObject1";
78     const char* FIELD_SIGNATURE = "Ljava/lang/Object;";
79     const char* INSTANCE_NAME = "testedInstance1";
80     const char* INSTANCE_SIGNATURE = "Lnsk/jvmti/scenarios/multienv/MA04/ma04t002;";
81     jfieldID fid = NULL;
82 
83     NSK_DISPLAY0("Obtain tested object from a static field of debugee class\n");
84 
85     NSK_DISPLAY1("Find class: %s\n", CLASS_NAME);
86     if (!NSK_JNI_VERIFY(jni, (testedClass =
87             NSK_CPP_STUB2(FindClass, jni, CLASS_NAME)) != NULL))
88         return NSK_FALSE;
89 
90     if (!NSK_JNI_VERIFY(jni, (testedClass =
91             NSK_CPP_STUB2(NewGlobalRef, jni, testedClass)) != NULL))
92         return NSK_FALSE;
93 
94     NSK_DISPLAY2("Find field: %s:%s\n", FIELD_NAME, FIELD_SIGNATURE);
95     if (!NSK_JNI_VERIFY(jni, (fid =
96             NSK_CPP_STUB4(GetStaticFieldID, jni, testedClass,
97                 FIELD_NAME, FIELD_SIGNATURE)) != NULL))
98         return NSK_FALSE;
99 
100     if (!NSK_JNI_VERIFY(jni, (testedObject =
101             NSK_CPP_STUB3(GetStaticObjectField, jni, testedClass, fid)) != NULL))
102         return NSK_FALSE;
103 
104     NSK_DISPLAY2("Find class instance: %s:%s\n",
105         INSTANCE_NAME, INSTANCE_SIGNATURE);
106     if (!NSK_JNI_VERIFY(jni, (fid =
107             NSK_CPP_STUB4(GetStaticFieldID, jni, testedClass,
108                 INSTANCE_NAME, INSTANCE_SIGNATURE)) != NULL))
109         return NSK_FALSE;
110 
111     if (!NSK_JNI_VERIFY(jni, (testedInstance =
112             NSK_CPP_STUB3(GetStaticObjectField, jni, testedClass, fid)) != NULL))
113         return NSK_FALSE;
114 
115     return NSK_TRUE;
116 }
117 
118 /* ========================================================================== */
119 
120 /** Agent algorithm. */
121 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * jni,void * arg)122 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
123     jint dummy;
124 
125     if (!nsk_jvmti_waitForSync(timeout))
126         return;
127 
128     if (!prepare(jni)) {
129         nsk_jvmti_setFailStatus();
130         return;
131     }
132 
133     NSK_DISPLAY0("Testcase #1: check that there are no tagged objects\n");
134 
135     ObjectsCount = 0;
136     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
137             JVMTI_HEAP_OBJECT_EITHER, heap_object_callback, &dummy))) {
138         nsk_jvmti_setFailStatus();
139         return;
140     }
141     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
142     if (ObjectsCount != 0) {
143         NSK_COMPLAIN1("Some objects were unexpectedly tagged: %d\n",
144             ObjectsCount);
145         nsk_jvmti_setFailStatus();
146     }
147 
148     ObjectsCount = 0;
149     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
150             JVMTI_HEAP_OBJECT_TAGGED, heap_object_callback, &dummy))) {
151         nsk_jvmti_setFailStatus();
152         return;
153     }
154     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
155     if (ObjectsCount != 0) {
156         NSK_COMPLAIN1("Some objects were unexpectedly tagged: %d\n",
157             ObjectsCount);
158         nsk_jvmti_setFailStatus();
159     }
160 
161     ObjectsCount = 0;
162     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(IterateOverInstancesOfClass, jvmti,
163             testedClass, JVMTI_HEAP_OBJECT_EITHER, heap_object_callback, &dummy))) {
164         nsk_jvmti_setFailStatus();
165         return;
166     }
167     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
168     if (ObjectsCount != 0) {
169         NSK_COMPLAIN1("Some class instances were unexpectedly tagged: %d\n",
170             ObjectsCount);
171         nsk_jvmti_setFailStatus();
172     }
173 
174     ObjectsCount = 0;
175     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(IterateOverInstancesOfClass, jvmti,
176             testedClass, JVMTI_HEAP_OBJECT_TAGGED, heap_object_callback, &dummy))) {
177         nsk_jvmti_setFailStatus();
178         return;
179     }
180     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
181     if (ObjectsCount != 0) {
182         NSK_COMPLAIN1("Some class instances were unexpectedly tagged: %d\n",
183             ObjectsCount);
184         nsk_jvmti_setFailStatus();
185     }
186 
187     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, testedObject,
188             SAMPLE_TAG))) {
189         nsk_jvmti_setFailStatus();
190         return;
191     }
192 
193     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
194         return;
195     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
196         return;
197 
198 
199     NSK_DISPLAY0("Testcase #2: check that there is only one object tagged\n");
200 
201     ObjectsCount = 0;
202     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
203             JVMTI_HEAP_OBJECT_EITHER, heap_object_callback, &dummy))) {
204         nsk_jvmti_setFailStatus();
205         return;
206     }
207     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
208     if (ObjectsCount != 1) {
209         NSK_COMPLAIN1("Expected 1 object to be tagged: %d\n", ObjectsCount);
210         nsk_jvmti_setFailStatus();
211     }
212 
213     ObjectsCount = 0;
214     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
215             JVMTI_HEAP_OBJECT_TAGGED, heap_object_callback, &dummy))) {
216         nsk_jvmti_setFailStatus();
217         return;
218     }
219     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
220     if (ObjectsCount != 1) {
221         NSK_COMPLAIN1("Expected 1 object to be tagged: %d\n", ObjectsCount);
222         nsk_jvmti_setFailStatus();
223     }
224 
225     ObjectsCount = 0;
226     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
227             JVMTI_HEAP_OBJECT_UNTAGGED, heap_object_callback, &dummy))) {
228         nsk_jvmti_setFailStatus();
229         return;
230     }
231     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
232     if (ObjectsCount != 0) {
233         NSK_COMPLAIN1("Some tagged objects were unexpectedly shown as untagged: %d\n",
234             ObjectsCount);
235         nsk_jvmti_setFailStatus();
236     }
237 
238     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, testedInstance,
239             SAMPLE_TAG))) {
240         nsk_jvmti_setFailStatus();
241         return;
242     }
243 
244     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
245         return;
246     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
247         return;
248 
249 
250     NSK_DISPLAY0("Testcase #3: check that there is only one class object tagged\n");
251 
252     ObjectsCount = 0;
253     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(IterateOverInstancesOfClass, jvmti,
254             testedClass, JVMTI_HEAP_OBJECT_EITHER, heap_object_callback, &dummy))) {
255         nsk_jvmti_setFailStatus();
256         return;
257     }
258     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
259     if (ObjectsCount != 1) {
260         NSK_COMPLAIN1("Expected 1 class instance to be tagged: %d\n",
261             ObjectsCount);
262         nsk_jvmti_setFailStatus();
263     }
264 
265     ObjectsCount = 0;
266     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(IterateOverInstancesOfClass, jvmti,
267             testedClass, JVMTI_HEAP_OBJECT_EITHER, heap_object_callback, &dummy))) {
268         nsk_jvmti_setFailStatus();
269         return;
270     }
271     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
272     if (ObjectsCount != 1) {
273         NSK_COMPLAIN1("Expected 1 class instance to be tagged: %d\n",
274             ObjectsCount);
275         nsk_jvmti_setFailStatus();
276     }
277 
278     ObjectsCount = 0;
279     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(IterateOverHeap, jvmti,
280             JVMTI_HEAP_OBJECT_UNTAGGED, heap_object_callback, &dummy))) {
281         nsk_jvmti_setFailStatus();
282         return;
283     }
284     NSK_DISPLAY1("ObjectsCount = %d\n", ObjectsCount);
285     if (ObjectsCount != 0) {
286         NSK_COMPLAIN1("Some tagged class instances were unexpectedly shown as untagged: %d\n",
287             ObjectsCount);
288         nsk_jvmti_setFailStatus();
289     }
290 
291 
292     NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, testedClass));
293 
294     if (!nsk_jvmti_resumeSync())
295         return;
296 }
297 
298 /* ========================================================================== */
299 
300 /** Agent library initialization. */
301 #ifdef STATIC_BUILD
Agent_OnLoad_ma04t002(JavaVM * jvm,char * options,void * reserved)302 JNIEXPORT jint JNICALL Agent_OnLoad_ma04t002(JavaVM *jvm, char *options, void *reserved) {
303     return Agent_Initialize(jvm, options, reserved);
304 }
Agent_OnAttach_ma04t002(JavaVM * jvm,char * options,void * reserved)305 JNIEXPORT jint JNICALL Agent_OnAttach_ma04t002(JavaVM *jvm, char *options, void *reserved) {
306     return Agent_Initialize(jvm, options, reserved);
307 }
JNI_OnLoad_ma04t002(JavaVM * jvm,char * options,void * reserved)308 JNIEXPORT jint JNI_OnLoad_ma04t002(JavaVM *jvm, char *options, void *reserved) {
309     return JNI_VERSION_1_8;
310 }
311 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)312 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
313     jvmtiEnv* jvmti = NULL;
314     jvmtiEventCallbacks callbacks;
315     jvmtiCapabilities caps;
316 
317     NSK_DISPLAY0("Agent_OnLoad\n");
318 
319     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
320         return JNI_ERR;
321 
322     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
323 
324     if (!NSK_VERIFY((jvmti =
325             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
326         return JNI_ERR;
327 
328     memset(&caps, 0, sizeof(caps));
329     caps.can_tag_objects = 1;
330     caps.can_generate_object_free_events = 1;
331     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
332         return JNI_ERR;
333     }
334 
335     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
336         return JNI_ERR;
337 
338     memset(&callbacks, 0, sizeof(callbacks));
339     if (!NSK_VERIFY(nsk_jvmti_init_MA(&callbacks)))
340         return JNI_ERR;
341 
342     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
343             jvmti, JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)))
344         return JNI_ERR;
345 
346     return JNI_OK;
347 }
348 
349 /* ========================================================================== */
350 
351 #ifdef __cplusplus
352 }
353 #endif
354