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