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 extern "C" {
35
36 /* ========================================================================== */
37
38 /* scaffold objects */
39 static jlong timeout = 0;
40
41 /* test objects */
42 static jobject testedObject = NULL;
43 static int ObjectFreeEventsCount = 0;
44
45 /* ========================================================================== */
46
47 /** callback functions **/
48
ObjectFree(jvmtiEnv * jvmti_env,jlong tag)49 void JNICALL ObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
50 char buffer[32], buffer2[32];
51
52 ObjectFreeEventsCount++;
53
54 NSK_DISPLAY1("ObjectFree event, tag = %s\n", jlong_to_string(tag, buffer));
55 if (tag != SAMPLE_TAG) {
56 if (tag == 0) {
57 NSK_COMPLAIN0("testedObject not tagged\n");
58 } else {
59 NSK_COMPLAIN2("testedObject tagged incorrectly, expected=%s, got=%s\n",
60 jlong_to_string(SAMPLE_TAG, buffer),
61 jlong_to_string(tag, buffer2));
62 }
63 nsk_jvmti_setFailStatus();
64 }
65 }
66
VMDeath(jvmtiEnv * jvmti_env,JNIEnv * env)67 void JNICALL VMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) {
68 NSK_DISPLAY0("VMDeath event\n");
69
70 if (ObjectFreeEventsCount == 0) {
71 NSK_DISPLAY0("Warning: no object free events\n");
72 }
73
74 if (nsk_jvmti_isFailStatus()) {
75 exit(NSK_STATUS_BASE + NSK_STATUS_FAILED);
76 }
77 }
78
79 /* ========================================================================== */
80
prepare(JNIEnv * jni)81 static int prepare(JNIEnv* jni) {
82 const char* CLASS_NAME = "nsk/jvmti/scenarios/multienv/MA04/ma04t003";
83 const char* FIELD_NAME = "testedObject1";
84 const char* FIELD_SIGNATURE = "Ljava/lang/Object;";
85 jclass cls = NULL;
86 jfieldID fid = NULL;
87
88 NSK_DISPLAY0("Obtain tested object from a static field of debugee class\n");
89
90 NSK_DISPLAY1("Find class: %s\n", CLASS_NAME);
91 if (!NSK_JNI_VERIFY(jni, (cls = jni->FindClass(CLASS_NAME)) != 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 jni->GetStaticFieldID(cls, FIELD_NAME, FIELD_SIGNATURE)) != NULL))
97 return NSK_FALSE;
98
99 if (!NSK_JNI_VERIFY(jni, (testedObject = jni->GetStaticObjectField(cls, fid)) != NULL))
100 return NSK_FALSE;
101
102 if (!NSK_JNI_VERIFY(jni, (testedObject = jni->NewGlobalRef(testedObject)) != NULL))
103 return NSK_FALSE;
104
105 return NSK_TRUE;
106 }
107
108 /* ========================================================================== */
109
110 /** Agent algorithm. */
111 static void JNICALL
agentProc(jvmtiEnv * jvmti,JNIEnv * jni,void * arg)112 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
113
114 if (!nsk_jvmti_waitForSync(timeout))
115 return;
116
117 if (!prepare(jni)) {
118 nsk_jvmti_setFailStatus();
119 return;
120 }
121
122 NSK_DISPLAY0("Set tag on testedObject\n");
123 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(testedObject, SAMPLE_TAG))) {
124 nsk_jvmti_setFailStatus();
125 return;
126 }
127
128 NSK_TRACE(jni->DeleteGlobalRef(testedObject));
129
130 if (!nsk_jvmti_resumeSync())
131 return;
132 }
133
134 /* ========================================================================== */
135
136 /** Agent library initialization. */
137 #ifdef STATIC_BUILD
Agent_OnLoad_ma04t003(JavaVM * jvm,char * options,void * reserved)138 JNIEXPORT jint JNICALL Agent_OnLoad_ma04t003(JavaVM *jvm, char *options, void *reserved) {
139 return Agent_Initialize(jvm, options, reserved);
140 }
Agent_OnAttach_ma04t003(JavaVM * jvm,char * options,void * reserved)141 JNIEXPORT jint JNICALL Agent_OnAttach_ma04t003(JavaVM *jvm, char *options, void *reserved) {
142 return Agent_Initialize(jvm, options, reserved);
143 }
JNI_OnLoad_ma04t003(JavaVM * jvm,char * options,void * reserved)144 JNIEXPORT jint JNI_OnLoad_ma04t003(JavaVM *jvm, char *options, void *reserved) {
145 return JNI_VERSION_1_8;
146 }
147 #endif
Agent_Initialize(JavaVM * jvm,char * options,void * reserved)148 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
149 jvmtiEnv* jvmti = NULL;
150 jvmtiEventCallbacks callbacks;
151 jvmtiCapabilities caps;
152
153 NSK_DISPLAY0("Agent_OnLoad\n");
154
155 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
156 return JNI_ERR;
157
158 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
159
160 if (!NSK_VERIFY((jvmti =
161 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
162 return JNI_ERR;
163
164 memset(&caps, 0, sizeof(caps));
165 caps.can_tag_objects = 1;
166 caps.can_generate_object_free_events = 1;
167 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
168 return JNI_ERR;
169 }
170
171 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
172 return JNI_ERR;
173
174 memset(&callbacks, 0, sizeof(callbacks));
175 callbacks.ObjectFree = &ObjectFree;
176 callbacks.VMDeath = &VMDeath;
177 if (!NSK_VERIFY(nsk_jvmti_init_MA(&callbacks)))
178 return JNI_ERR;
179
180 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL)))
181 return JNI_ERR;
182
183 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
184 return JNI_ERR;
185
186 return JNI_OK;
187 }
188
189 /* ========================================================================== */
190
191 }
192