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
30 extern "C" {
31
32 /* ============================================================================= */
33
34 static jlong timeout = 0;
35
36 static long objCounter = 0;
37 static int userData = 0;
38 static jvmtiEnv* st_jvmti = NULL;
39
40 /* ============================================================================= */
41
42 /* ============================================================================= */
43
44
45 /* jvmtiHeapRootCallback */
46 jvmtiIterationControl JNICALL
heapRootCallback(jvmtiHeapRootKind root_kind,jlong class_tag,jlong size,jlong * tag_ptr,void * user_data)47 heapRootCallback(jvmtiHeapRootKind root_kind,
48 jlong class_tag,
49 jlong size,
50 jlong* tag_ptr,
51 void* user_data) {
52
53 jrawMonitorID monitor_ptr = NULL;
54
55 *tag_ptr = (jlong)++objCounter;
56
57 if (!NSK_JVMTI_VERIFY(st_jvmti->CreateRawMonitor("heapRootMonitor", &monitor_ptr))) {
58 nsk_jvmti_setFailStatus();
59 return JVMTI_ITERATION_ABORT;
60 }
61
62 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
63 nsk_jvmti_setFailStatus();
64 return JVMTI_ITERATION_ABORT;
65 }
66
67 /* Enter second time */
68 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
69 nsk_jvmti_setFailStatus();
70 return JVMTI_ITERATION_ABORT;
71 }
72
73 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorWait(monitor_ptr, (jlong)1))) {
74 nsk_jvmti_setFailStatus();
75 }
76
77 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotify(monitor_ptr))) {
78 nsk_jvmti_setFailStatus();
79 }
80
81 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotifyAll(monitor_ptr))) {
82 nsk_jvmti_setFailStatus();
83 }
84
85 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
86 nsk_jvmti_setFailStatus();
87 return JVMTI_ITERATION_ABORT;
88 }
89
90 /* Exit second time */
91 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
92 nsk_jvmti_setFailStatus();
93 return JVMTI_ITERATION_ABORT;
94 }
95
96 if (!NSK_JVMTI_VERIFY(st_jvmti->DestroyRawMonitor(monitor_ptr))) {
97 nsk_jvmti_setFailStatus();
98 }
99 /*
100 NSK_DISPLAY1("heapRootCallback: %d\n", objCounter);
101 */
102 return JVMTI_ITERATION_CONTINUE;
103 }
104
105 /* jvmtiStackReferenceCallback */
106 jvmtiIterationControl JNICALL
stackReferenceCallback(jvmtiHeapRootKind root_kind,jlong class_tag,jlong size,jlong * tag_ptr,jlong thread_tag,jint depth,jmethodID method,jint slot,void * user_data)107 stackReferenceCallback(jvmtiHeapRootKind root_kind,
108 jlong class_tag,
109 jlong size,
110 jlong* tag_ptr,
111 jlong thread_tag,
112 jint depth,
113 jmethodID method,
114 jint slot,
115 void* user_data) {
116
117 jrawMonitorID monitor_ptr = NULL;
118
119 *tag_ptr = (jlong)++objCounter;
120
121 if (!NSK_JVMTI_VERIFY(st_jvmti->CreateRawMonitor("stackRefMonitor", &monitor_ptr))) {
122 nsk_jvmti_setFailStatus();
123 return JVMTI_ITERATION_ABORT;
124 }
125
126 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
127 nsk_jvmti_setFailStatus();
128 return JVMTI_ITERATION_ABORT;
129 }
130
131 /* Enter second time */
132 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
133 nsk_jvmti_setFailStatus();
134 return JVMTI_ITERATION_ABORT;
135 }
136
137 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorWait(monitor_ptr, (jlong)1))) {
138 nsk_jvmti_setFailStatus();
139 }
140
141 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotify(monitor_ptr))) {
142 nsk_jvmti_setFailStatus();
143 }
144
145 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotifyAll(monitor_ptr))) {
146 nsk_jvmti_setFailStatus();
147 }
148
149 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
150 nsk_jvmti_setFailStatus();
151 return JVMTI_ITERATION_ABORT;
152 }
153
154 /* Exit second time */
155 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
156 nsk_jvmti_setFailStatus();
157 return JVMTI_ITERATION_ABORT;
158 }
159
160 if (!NSK_JVMTI_VERIFY(st_jvmti->DestroyRawMonitor(monitor_ptr))) {
161 nsk_jvmti_setFailStatus();
162 }
163 /*
164 NSK_DISPLAY1("stackRefenceCallback: %d\n", objCounter);
165 */
166 return JVMTI_ITERATION_CONTINUE;
167 }
168
169
170 /* jvmtiObjectReferenceCallback */
171 jvmtiIterationControl JNICALL
objectReferenceCallback(jvmtiObjectReferenceKind reference_kind,jlong class_tag,jlong size,jlong * tag_ptr,jlong referrer_tag,jint referrer_index,void * user_data)172 objectReferenceCallback(jvmtiObjectReferenceKind reference_kind,
173 jlong class_tag,
174 jlong size,
175 jlong* tag_ptr,
176 jlong referrer_tag,
177 jint referrer_index,
178 void* user_data) {
179
180 jrawMonitorID monitor_ptr = NULL;
181
182 *tag_ptr = (jlong)++objCounter;
183
184 if (!NSK_JVMTI_VERIFY(st_jvmti->CreateRawMonitor("objRefMonitor", &monitor_ptr))) {
185 nsk_jvmti_setFailStatus();
186 return JVMTI_ITERATION_ABORT;
187 }
188
189 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
190 nsk_jvmti_setFailStatus();
191 return JVMTI_ITERATION_ABORT;
192 }
193
194 /* Enter second time */
195 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorEnter(monitor_ptr))) {
196 nsk_jvmti_setFailStatus();
197 return JVMTI_ITERATION_ABORT;
198 }
199
200 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorWait(monitor_ptr, (jlong)1))) {
201 nsk_jvmti_setFailStatus();
202 }
203
204 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotify(monitor_ptr))) {
205 nsk_jvmti_setFailStatus();
206 }
207
208 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorNotifyAll(monitor_ptr))) {
209 nsk_jvmti_setFailStatus();
210 }
211
212 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
213 nsk_jvmti_setFailStatus();
214 return JVMTI_ITERATION_ABORT;
215 }
216
217 /* Exit second time */
218 if (!NSK_JVMTI_VERIFY(st_jvmti->RawMonitorExit(monitor_ptr))) {
219 nsk_jvmti_setFailStatus();
220 return JVMTI_ITERATION_ABORT;
221 }
222
223 if (!NSK_JVMTI_VERIFY(st_jvmti->DestroyRawMonitor(monitor_ptr))) {
224 nsk_jvmti_setFailStatus();
225 }
226
227 NSK_DISPLAY1("objectRefenceCallback: %d\n", objCounter);
228 return JVMTI_ITERATION_ABORT;
229 }
230
231 /* ============================================================================= */
232
233 /** Agent algorithm. */
234 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * jni,void * arg)235 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
236
237 NSK_DISPLAY0("Wait for debugee start\n");
238 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
239 return;
240
241 {
242 do {
243 NSK_DISPLAY0("Calling IterateOverReachableObjects\n");
244 {
245 if (!NSK_JVMTI_VERIFY(
246 jvmti->IterateOverReachableObjects(heapRootCallback,
247 stackReferenceCallback,
248 objectReferenceCallback,
249 &userData))) {
250 nsk_jvmti_setFailStatus();
251 break;
252 }
253 }
254
255 if (objCounter == 0) {
256 NSK_COMPLAIN0("IterateOverReachableObjects call had not visited any object\n");
257 nsk_jvmti_setFailStatus();
258 break;
259 } else {
260 NSK_DISPLAY1("Number of objects the IterateOverReachableObjects visited: %d\n", objCounter);
261 }
262
263 } while (0);
264 }
265
266 NSK_DISPLAY0("Let debugee to finish\n");
267 if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
268 return;
269 }
270
271 /* ============================================================================= */
272
273 /* ============================================================================= */
274
275 /** Agent library initialization. */
276 #ifdef STATIC_BUILD
Agent_OnLoad_iterreachobj003(JavaVM * jvm,char * options,void * reserved)277 JNIEXPORT jint JNICALL Agent_OnLoad_iterreachobj003(JavaVM *jvm, char *options, void *reserved) {
278 return Agent_Initialize(jvm, options, reserved);
279 }
Agent_OnAttach_iterreachobj003(JavaVM * jvm,char * options,void * reserved)280 JNIEXPORT jint JNICALL Agent_OnAttach_iterreachobj003(JavaVM *jvm, char *options, void *reserved) {
281 return Agent_Initialize(jvm, options, reserved);
282 }
JNI_OnLoad_iterreachobj003(JavaVM * jvm,char * options,void * reserved)283 JNIEXPORT jint JNI_OnLoad_iterreachobj003(JavaVM *jvm, char *options, void *reserved) {
284 return JNI_VERSION_1_8;
285 }
286 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)287 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
288 jvmtiEnv* jvmti = NULL;
289
290 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
291 return JNI_ERR;
292
293 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
294
295 if (!NSK_VERIFY((jvmti =
296 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
297 return JNI_ERR;
298
299 /* save pointer to environment to use it in callbacks */
300 st_jvmti = jvmti;
301
302 {
303 jvmtiCapabilities caps;
304
305 memset(&caps, 0, sizeof(caps));
306 caps.can_tag_objects = 1;
307 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
308 return JNI_ERR;
309 }
310 }
311
312 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
313 return JNI_ERR;
314
315 return JNI_OK;
316 }
317
318 /* ============================================================================= */
319
320 }
321