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