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 36 static long objCounter = 0; 37 static int userData = 0; 38 static jvmtiEnv* st_jvmti = NULL; 39 static const char *storage_data = "local_storage_data"; 40 static void *storage_ptr = NULL; 41 42 /* ============================================================================= */ 43 44 /* ============================================================================= */ 45 46 47 /* jvmtiHeapRootCallback */ 48 jvmtiIterationControl JNICALL 49 heapRootCallback( jvmtiHeapRootKind root_kind, 50 jlong class_tag, 51 jlong size, 52 jlong* tag_ptr, 53 void* user_data) { 54 55 *tag_ptr = (jlong)++objCounter; 56 57 if (!NSK_JVMTI_VERIFY(st_jvmti->SetEnvironmentLocalStorage(storage_data))) { 58 nsk_jvmti_setFailStatus(); 59 return JVMTI_ITERATION_ABORT; 60 } 61 62 if (!NSK_JVMTI_VERIFY(st_jvmti->GetEnvironmentLocalStorage(&storage_ptr))) { 63 nsk_jvmti_setFailStatus(); 64 return JVMTI_ITERATION_ABORT; 65 } 66 67 if (storage_data != storage_ptr) { 68 NSK_COMPLAIN2("heapRootCallback: Local storage address was corrupted: %p ,\n\texpected value: %p\n", 69 storage_ptr, storage_data); 70 nsk_jvmti_setFailStatus(); 71 return JVMTI_ITERATION_ABORT; 72 } 73 74 if (strcmp(storage_data, (char *)storage_ptr) != 0) { 75 NSK_COMPLAIN2("heapRootCallback: Local storage was corrupted: %s ,\n\texpected value: %s\n", 76 (char *)storage_ptr, storage_data ); 77 nsk_jvmti_setFailStatus(); 78 return JVMTI_ITERATION_ABORT; 79 } 80 81 /* 82 NSK_DISPLAY1("heapRootCallback: %d\n", objCounter); 83 */ 84 return JVMTI_ITERATION_CONTINUE; 85 } 86 87 /* jvmtiStackReferenceCallback */ 88 jvmtiIterationControl JNICALL 89 stackReferenceCallback( jvmtiHeapRootKind root_kind, 90 jlong class_tag, 91 jlong size, 92 jlong* tag_ptr, 93 jlong thread_tag, 94 jint depth, 95 jmethodID method, 96 jint slot, 97 void* user_data) { 98 99 *tag_ptr = (jlong)++objCounter; 100 101 if (!NSK_JVMTI_VERIFY(st_jvmti->SetEnvironmentLocalStorage(storage_data))) { 102 nsk_jvmti_setFailStatus(); 103 return JVMTI_ITERATION_ABORT; 104 } 105 106 if (!NSK_JVMTI_VERIFY(st_jvmti->GetEnvironmentLocalStorage(&storage_ptr))) { 107 nsk_jvmti_setFailStatus(); 108 return JVMTI_ITERATION_ABORT; 109 } 110 111 if (storage_data != storage_ptr) { 112 NSK_COMPLAIN2("stackReferenceCallback: Local storage address was corrupted: %p ,\n\texpected value: %p\n", 113 storage_ptr, storage_data); 114 nsk_jvmti_setFailStatus(); 115 return JVMTI_ITERATION_ABORT; 116 } 117 118 if (strcmp(storage_data, (char *)storage_ptr) != 0) { 119 NSK_COMPLAIN2("stackReferenceCallback: Local storage was corrupted: %s ,\n\texpected value: %s\n", 120 (char *)storage_ptr, storage_data ); 121 nsk_jvmti_setFailStatus(); 122 return JVMTI_ITERATION_ABORT; 123 } 124 125 /* 126 NSK_DISPLAY1("stackRefenceCallback: %d\n", objCounter); 127 */ 128 return JVMTI_ITERATION_CONTINUE; 129 } 130 131 132 /* jvmtiObjectReferenceCallback */ 133 jvmtiIterationControl JNICALL 134 objectReferenceCallback( jvmtiObjectReferenceKind reference_kind, 135 jlong class_tag, 136 jlong size, 137 jlong* tag_ptr, 138 jlong referrer_tag, 139 jint referrer_index, 140 void* user_data) { 141 142 *tag_ptr = (jlong)++objCounter; 143 144 if (!NSK_JVMTI_VERIFY(st_jvmti->SetEnvironmentLocalStorage(storage_data))) { 145 nsk_jvmti_setFailStatus(); 146 return JVMTI_ITERATION_ABORT; 147 } 148 149 if (!NSK_JVMTI_VERIFY(st_jvmti->GetEnvironmentLocalStorage(&storage_ptr))) { 150 nsk_jvmti_setFailStatus(); 151 return JVMTI_ITERATION_ABORT; 152 } 153 154 if (storage_data != storage_ptr) { 155 NSK_COMPLAIN2("objectReferenceCallback: Local storage address was corrupted: %p ,\n\texpected value: %p\n", 156 storage_ptr, storage_data); 157 nsk_jvmti_setFailStatus(); 158 return JVMTI_ITERATION_ABORT; 159 } 160 161 if (strcmp(storage_data, (char *)storage_ptr) != 0) { 162 NSK_COMPLAIN2("objectReferenceCallback: Local storage was corrupted: %s ,\n\texpected value: %s\n", 163 (char *)storage_ptr, storage_data ); 164 nsk_jvmti_setFailStatus(); 165 return JVMTI_ITERATION_ABORT; 166 } 167 168 NSK_DISPLAY1("objectRefenceCallback: %d\n", objCounter); 169 return JVMTI_ITERATION_ABORT; 170 } 171 172 /* ============================================================================= */ 173 174 /** Agent algorithm. */ 175 static void JNICALL 176 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 177 178 NSK_DISPLAY0("Wait for debugee start\n"); 179 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 180 return; 181 182 { 183 do { 184 NSK_DISPLAY0("Calling IterateOverReachableObjects\n"); 185 { 186 if (!NSK_JVMTI_VERIFY( 187 jvmti->IterateOverReachableObjects(heapRootCallback, 188 stackReferenceCallback, 189 objectReferenceCallback, 190 &userData))) { 191 nsk_jvmti_setFailStatus(); 192 break; 193 } 194 } 195 196 if (objCounter == 0) { 197 NSK_COMPLAIN0("IterateOverReachableObjects call had not visited any object\n"); 198 nsk_jvmti_setFailStatus(); 199 break; 200 } else { 201 NSK_DISPLAY1("Number of objects the IterateOverReachableObjects visited: %d\n", objCounter); 202 } 203 204 } while (0); 205 } 206 207 NSK_DISPLAY0("Let debugee to finish\n"); 208 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 209 return; 210 } 211 212 /* ============================================================================= */ 213 214 /* ============================================================================= */ 215 216 /** Agent library initialization. */ 217 #ifdef STATIC_BUILD 218 JNIEXPORT jint JNICALL Agent_OnLoad_iterreachobj004(JavaVM *jvm, char *options, void *reserved) { 219 return Agent_Initialize(jvm, options, reserved); 220 } 221 JNIEXPORT jint JNICALL Agent_OnAttach_iterreachobj004(JavaVM *jvm, char *options, void *reserved) { 222 return Agent_Initialize(jvm, options, reserved); 223 } 224 JNIEXPORT jint JNI_OnLoad_iterreachobj004(JavaVM *jvm, char *options, void *reserved) { 225 return JNI_VERSION_1_8; 226 } 227 #endif 228 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 229 jvmtiEnv* jvmti = NULL; 230 231 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 232 return JNI_ERR; 233 234 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 235 236 if (!NSK_VERIFY((jvmti = 237 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 238 return JNI_ERR; 239 240 /* save pointer to environment to use it in callbacks */ 241 st_jvmti = jvmti; 242 243 { 244 jvmtiCapabilities caps; 245 246 memset(&caps, 0, sizeof(caps)); 247 caps.can_tag_objects = 1; 248 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) { 249 return JNI_ERR; 250 } 251 } 252 253 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 254 return JNI_ERR; 255 256 return JNI_OK; 257 } 258 259 /* ============================================================================= */ 260 261 }