1 /* 2 * Copyright (c) 2003, 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 "jvmti.h" 27 #include "agent_common.h" 28 #include "jni_tools.h" 29 #include "jvmti_tools.h" 30 31 extern "C" { 32 33 /* ============================================================================= */ 34 35 static jlong timeout = 0; 36 37 #define STATUS_FAIL 97 38 39 /* events */ 40 41 #define EVENTS_COUNT 2 42 static jvmtiEvent events[EVENTS_COUNT] = { 43 JVMTI_EVENT_VM_INIT, 44 JVMTI_EVENT_VM_DEATH 45 }; 46 47 /* storage data */ 48 49 #define STORAGE_DATA_SIZE 1024 50 #define STORAGE_DATA_CHAR 'X' 51 52 typedef struct _StorageStructure { 53 char data[STORAGE_DATA_SIZE]; 54 } StorageStructure; 55 56 static StorageStructure storageData; 57 static StorageStructure* initialStorage = &storageData; 58 59 /* ============================================================================= */ 60 61 /** Fill storage data with given char */ 62 static void fillEnvStorage(StorageStructure* storage) { 63 NSK_DISPLAY2("Fill storage data with char %c for size: %d bytes\n", 64 (char)STORAGE_DATA_CHAR, (int)STORAGE_DATA_SIZE); 65 memset(storage->data, STORAGE_DATA_CHAR, STORAGE_DATA_SIZE); 66 NSK_DISPLAY0(" ... ok\n"); 67 } 68 69 /** 70 * Set JVMTI environment local storage with given pinter. 71 * @returns NSK_FALSE if any error occured. 72 */ 73 static int setEnvStorage(jvmtiEnv* jvmti, StorageStructure* storage, const char where[]) { 74 75 NSK_DISPLAY1("Set local storage for current JVMTI env: 0x%p\n", (void*)storage); 76 if (!NSK_JVMTI_VERIFY( 77 NSK_CPP_STUB2(SetEnvironmentLocalStorage, jvmti, storage))) { 78 return NSK_FALSE; 79 } 80 NSK_DISPLAY0(" ... ok\n"); 81 return NSK_TRUE; 82 } 83 84 /** 85 * Check JVMTI environment local storage. 86 * @returns NSK_FALSE if any error occured. 87 */ 88 static int checkEnvStorage(jvmtiEnv* jvmti, StorageStructure* initialStorage, const char where[]) { 89 StorageStructure* storage = NULL; 90 91 NSK_DISPLAY0("Get local storage for current JVMTI env\n"); 92 if (!NSK_JVMTI_VERIFY( 93 NSK_CPP_STUB2(GetEnvironmentLocalStorage, jvmti, (void**)&storage))) { 94 return NSK_FALSE; 95 } 96 NSK_DISPLAY1(" ... got storage: 0x%p\n", (void*)storage); 97 98 if (storage != initialStorage) { 99 NSK_COMPLAIN3("Wrong storage pointer returned for current JVMTI env in %s:\n" 100 "# got pointer: %p\n" 101 "# expected: %p\n", 102 where, 103 (void*)storage, (void*)initialStorage); 104 return NSK_FALSE; 105 } 106 107 { 108 int changed = 0; 109 int i; 110 111 for (i = 0; i < STORAGE_DATA_SIZE; i++) { 112 if (storage->data[i] != STORAGE_DATA_CHAR) { 113 changed++; 114 } 115 } 116 117 if (changed > 0) { 118 NSK_COMPLAIN3("Data changed in returned storage for current JVMTI env in %s:\n" 119 "# changed bytes: %d\n" 120 "# total bytes: %d\n", 121 where, 122 changed, STORAGE_DATA_SIZE); 123 return NSK_FALSE; 124 } 125 } 126 127 return NSK_TRUE; 128 } 129 130 /* ============================================================================= */ 131 132 /** Agent algorithm. */ 133 static void JNICALL 134 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 135 NSK_DISPLAY0("Wait for debugee to become ready\n"); 136 if (!nsk_jvmti_waitForSync(timeout)) 137 return; 138 139 NSK_DISPLAY0(">>> Testcase #3: Check env storage in agent thread\n"); 140 if (!checkEnvStorage(jvmti, initialStorage, "agent thread")) { 141 nsk_jvmti_setFailStatus(); 142 } 143 144 NSK_DISPLAY0("Let debugee to finish\n"); 145 if (!nsk_jvmti_resumeSync()) 146 return; 147 } 148 149 /* ============================================================================= */ 150 151 /** 152 * Callback for VM_INIT event. 153 */ 154 JNIEXPORT void JNICALL 155 callbackVMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) { 156 157 NSK_DISPLAY0(">>> Testcase #2: Check env storage in VM_INIT callback\n"); 158 if (!checkEnvStorage(jvmti, initialStorage, "VM_INIT callback")) { 159 nsk_jvmti_setFailStatus(); 160 } 161 162 } 163 164 /** 165 * Callback for VM_DEATH event. 166 */ 167 JNIEXPORT void JNICALL 168 callbackVMDeath(jvmtiEnv* jvmti, JNIEnv* jni) { 169 int success = NSK_TRUE; 170 171 NSK_DISPLAY0(">>> Testcase #4: Check env storage in VM_DEATH callback\n"); 172 success = checkEnvStorage(jvmti, initialStorage, "VM_DEATH callback"); 173 174 NSK_DISPLAY1("Disable events: %d events\n", EVENTS_COUNT); 175 if (!nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, events, NULL)) { 176 success = NSK_FALSE; 177 } else { 178 NSK_DISPLAY0(" ... disabled\n"); 179 } 180 181 if (!success) { 182 NSK_DISPLAY1("Exit with FAIL exit status: %d\n", STATUS_FAIL); 183 NSK_BEFORE_TRACE(exit(STATUS_FAIL)); 184 } 185 } 186 187 /* ============================================================================= */ 188 189 /** Agent library initialization. */ 190 #ifdef STATIC_BUILD 191 JNIEXPORT jint JNICALL Agent_OnLoad_setenvstor001(JavaVM *jvm, char *options, void *reserved) { 192 return Agent_Initialize(jvm, options, reserved); 193 } 194 JNIEXPORT jint JNICALL Agent_OnAttach_setenvstor001(JavaVM *jvm, char *options, void *reserved) { 195 return Agent_Initialize(jvm, options, reserved); 196 } 197 JNIEXPORT jint JNI_OnLoad_setenvstor001(JavaVM *jvm, char *options, void *reserved) { 198 return JNI_VERSION_1_8; 199 } 200 #endif 201 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 202 jvmtiEnv* jvmti = NULL; 203 204 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 205 return JNI_ERR; 206 207 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 208 209 if (!NSK_VERIFY((jvmti = 210 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 211 return JNI_ERR; 212 213 { 214 jvmtiEventCallbacks eventCallbacks; 215 216 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 217 eventCallbacks.VMInit = callbackVMInit; 218 eventCallbacks.VMDeath = callbackVMDeath; 219 if (!NSK_JVMTI_VERIFY( 220 NSK_CPP_STUB3(SetEventCallbacks, jvmti, 221 &eventCallbacks, sizeof(eventCallbacks)))) { 222 return JNI_ERR; 223 } 224 225 } 226 227 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 228 return JNI_ERR; 229 230 NSK_DISPLAY1(">>> Prepare storage data at pointer: 0x%p\n", initialStorage); 231 fillEnvStorage(initialStorage); 232 233 NSK_DISPLAY0(">>> Testcase #0: Set env storage in JVM_OnLoad()\n"); 234 if (!setEnvStorage(jvmti, initialStorage, "JVM_OnLoad()")) { 235 nsk_jvmti_setFailStatus(); 236 } 237 238 NSK_DISPLAY0(">>> Testcase #1: Check env storage in JVM_OnLoad()\n"); 239 if (!checkEnvStorage(jvmti, initialStorage, "JVM_OnLoad()")) { 240 nsk_jvmti_setFailStatus(); 241 } 242 243 NSK_DISPLAY1("Enable events: %d events\n", EVENTS_COUNT); 244 if (nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT, events, NULL)) { 245 NSK_DISPLAY0(" ... enabled\n"); 246 } 247 248 return JNI_OK; 249 } 250 251 /* ============================================================================= */ 252 253 }