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