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 static jvmtiEnv* st_jvmti = NULL;
  36 static const char *storage_data = "local_storage_data";
  37 static void *storage_ptr = NULL;
  38 
  39 
  40 /* ============================================================================= */
  41 
  42 jvmtiIterationControl JNICALL
  43 heapObjectCallback(jlong class_tag,
  44                    jlong size,
  45                    jlong* tag_ptr,
  46                    void* storage_data) {
  47 
  48     if (!NSK_JVMTI_VERIFY(
  49             st_jvmti->SetEnvironmentLocalStorage(storage_data))) {
  50         nsk_jvmti_setFailStatus();
  51     }
  52 
  53     if (!NSK_JVMTI_VERIFY(
  54             st_jvmti->GetEnvironmentLocalStorage(&storage_ptr))) {
  55         nsk_jvmti_setFailStatus();
  56     }
  57 
  58     /*  Iterate over only first object */
  59     return JVMTI_ITERATION_ABORT;
  60 }
  61 
  62 /* ============================================================================= */
  63 
  64 /** Agent algorithm. */
  65 static void JNICALL
  66 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
  67 
  68     NSK_DISPLAY0("Wait for debugee start\n");
  69     if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
  70         return;
  71 
  72     {
  73         NSK_DISPLAY0("Calling IterateOverHeap with filter JVMTI_HEAP_OBJECT_EITHER\n");
  74         {
  75             if (!NSK_JVMTI_VERIFY(
  76                     jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_EITHER, heapObjectCallback, (void *)storage_data))) {
  77                 nsk_jvmti_setFailStatus();
  78             }
  79         }
  80 
  81         if (storage_data != storage_ptr) {
  82             NSK_COMPLAIN2("Local storage address was corrupted: %p ,\n\texpected value: %p\n",
  83                              storage_ptr, storage_data);
  84             nsk_jvmti_setFailStatus();
  85         }
  86 
  87         if (strcmp(storage_data, (char *)storage_ptr) != 0) {
  88             NSK_COMPLAIN2("Local storage was corrupted: %s ,\n\texpected value: %s\n",
  89                              (char *)storage_ptr, storage_data);
  90             nsk_jvmti_setFailStatus();
  91         }
  92     }
  93 
  94     NSK_DISPLAY0("Let debugee to finish\n");
  95     if (!NSK_VERIFY(nsk_jvmti_resumeSync()))
  96         return;
  97 }
  98 
  99 /* ============================================================================= */
 100 
 101 /** Agent library initialization. */
 102 #ifdef STATIC_BUILD
 103 JNIEXPORT jint JNICALL Agent_OnLoad_iterheap006(JavaVM *jvm, char *options, void *reserved) {
 104     return Agent_Initialize(jvm, options, reserved);
 105 }
 106 JNIEXPORT jint JNICALL Agent_OnAttach_iterheap006(JavaVM *jvm, char *options, void *reserved) {
 107     return Agent_Initialize(jvm, options, reserved);
 108 }
 109 JNIEXPORT jint JNI_OnLoad_iterheap006(JavaVM *jvm, char *options, void *reserved) {
 110     return JNI_VERSION_1_8;
 111 }
 112 #endif
 113 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 114     jvmtiEnv* jvmti = NULL;
 115 
 116     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 117         return JNI_ERR;
 118 
 119     timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
 120 
 121     if (!NSK_VERIFY((jvmti =
 122             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
 123         return JNI_ERR;
 124 
 125     /* save pointer to environment to use it in callbacks */
 126     st_jvmti = jvmti;
 127 
 128     {
 129         jvmtiCapabilities caps;
 130 
 131         memset(&caps, 0, sizeof(caps));
 132         caps.can_tag_objects = 1;
 133         if (!NSK_JVMTI_VERIFY(
 134                 jvmti->AddCapabilities(&caps))) {
 135             return JNI_ERR;
 136         }
 137     }
 138 
 139     if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
 140         return JNI_ERR;
 141 
 142     return JNI_OK;
 143 }
 144 
 145 /* ============================================================================= */
 146 
 147 }