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 /* 25 This test case to test the following: 26 27 VMInit initial thread arg. 28 SetThreadLocalStorage and SetEnvironmentLocalStorage should allow 29 value to be set to NULL. 30 */ 31 32 #include <stdio.h> 33 #include <string.h> 34 #include <inttypes.h> 35 #include "jvmti.h" 36 #include "jni_tools.h" 37 #include "agent_common.h" 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 #ifndef JNI_ENV_ARG 44 45 #ifdef __cplusplus 46 #define JNI_ENV_ARG(x, y) y 47 #define JNI_ENV_ARG1(x) 48 #define JNI_ENV_PTR(x) x 49 #else 50 #define JNI_ENV_ARG(x,y) x, y 51 #define JNI_ENV_ARG1(x) x 52 #define JNI_ENV_PTR(x) (*x) 53 #endif 54 55 #endif 56 57 #define JVMTI_ENV_ARG JNI_ENV_ARG 58 #define JVMTI_ENV_ARG1 JNI_ENV_ARG1 59 #define JVMTI_ENV_PTR JNI_ENV_PTR 60 61 #define JVMTI_ERROR_CHECK(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;} 62 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); return res;} 63 64 #define JVMTI_ERROR_CHECK_VOID(str,res) if ( res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; } 65 66 #define JVMTI_ERROR_CHECK_EXPECTED_ERROR_VOID(str,res,err) if ( res != err) { printf(str); printf("unexpected error %d\n",res); iGlobalStatus = 2; } 67 68 jvmtiEnv *jvmti; 69 jint iGlobalStatus = 0; 70 static jvmtiEventCallbacks callbacks; 71 72 int printdump = 0; 73 74 75 void debug_printf(char *fmt, ...) { 76 va_list args; 77 78 va_start(args, fmt); 79 if (printdump) { 80 vprintf(fmt, args); 81 } 82 va_end(args); 83 } 84 85 86 intptr_t get_env_local() { 87 jvmtiError res; 88 void *val; 89 res = JVMTI_ENV_PTR(jvmti)->GetEnvironmentLocalStorage(JVMTI_ENV_ARG(jvmti, &val)); 90 JVMTI_ERROR_CHECK("GetEnvironmentLocalStorage returned error", res); 91 return (intptr_t)val; 92 } 93 94 void set_env_local(intptr_t x) { 95 jvmtiError res; 96 void *val = (void*)x; 97 res = JVMTI_ENV_PTR(jvmti)->SetEnvironmentLocalStorage(JVMTI_ENV_ARG(jvmti, val)); 98 JVMTI_ERROR_CHECK_VOID("SetEnvironmentLocalStorage returned error", res); 99 } 100 101 intptr_t get_thread_local(jthread thread) { 102 jvmtiError res; 103 void *val; 104 res = JVMTI_ENV_PTR(jvmti)->GetThreadLocalStorage(JVMTI_ENV_ARG(jvmti, thread), &val); 105 JVMTI_ERROR_CHECK("GetThreadLocalStorage returned error", res); 106 return (intptr_t)val; 107 } 108 109 void set_thread_local(jthread thread, intptr_t x) { 110 jvmtiError res; 111 void *val = (void*)x; 112 res = JVMTI_ENV_PTR(jvmti)->SetThreadLocalStorage(JVMTI_ENV_ARG(jvmti, thread), val); 113 JVMTI_ERROR_CHECK_VOID("SetThreadLocalStorage returned error", res); 114 } 115 116 void check_val(intptr_t x, intptr_t y, const char* msg) { 117 if (x != y) { 118 printf("Error in %s: expected %" PRIdPTR " to be %" PRIdPTR "\n", msg, x, y); 119 iGlobalStatus = 2; 120 } else if (printdump) { 121 printf("Correct in %s: expected %" PRIdPTR " to be %" PRIdPTR "\n", msg, x, y); 122 } 123 } 124 125 126 void JNICALL vmInit(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) { 127 check_val(get_thread_local(thread), 0, "thread initial"); 128 check_val(get_thread_local(NULL), 0, "thread initial"); 129 set_thread_local(thread, 35); 130 check_val(get_thread_local(thread), 35, "thread set non-zero"); 131 check_val(get_thread_local(NULL), 35, "thread set non-zero"); 132 set_thread_local(NULL, 0); 133 check_val(get_thread_local(thread), 0, "thread set zero"); 134 check_val(get_thread_local(NULL), 0, "thread set zero"); 135 136 check_val(get_env_local(), 14, "env set non-zero"); 137 set_env_local(77); 138 check_val(get_env_local(), 77, "env set non-zero"); 139 } 140 141 142 void init_callbacks() { 143 memset((void *)&callbacks, 0, sizeof(jvmtiEventCallbacks)); 144 callbacks.VMInit = vmInit; 145 } 146 147 #ifdef STATIC_BUILD 148 JNIEXPORT jint JNICALL Agent_OnLoad_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 149 return Agent_Initialize(jvm, options, reserved); 150 } 151 JNIEXPORT jint JNICALL Agent_OnAttach_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 152 return Agent_Initialize(jvm, options, reserved); 153 } 154 JNIEXPORT jint JNI_OnLoad_JvmtiTest(JavaVM *jvm, char *options, void *reserved) { 155 return JNI_VERSION_1_8; 156 } 157 #endif 158 jint Agent_Initialize(JavaVM * jvm, char *options, void *reserved) { 159 jint res; 160 161 if (options && strlen(options) > 0) { 162 if (strstr(options, "printdump")) { 163 printdump = 1; 164 } 165 } 166 167 res = JNI_ENV_PTR(jvm)-> 168 GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), JVMTI_VERSION_1_1); 169 if (res < 0) { 170 printf("Wrong result of a valid call to GetEnv!\n"); 171 return JNI_ERR; 172 } 173 174 check_val(get_env_local(), 0, "env initial"); 175 set_env_local(0); 176 check_val(get_env_local(), 0, "env set zero"); 177 set_env_local(14); 178 check_val(get_env_local(), 14, "env set non-zero"); 179 180 /* Enable events */ 181 init_callbacks(); 182 res = JVMTI_ENV_PTR(jvmti)->SetEventCallbacks(JVMTI_ENV_ARG(jvmti, &callbacks), sizeof(callbacks)); 183 JVMTI_ERROR_CHECK("SetEventCallbacks returned error", res); 184 185 res = JVMTI_ENV_PTR(jvmti)->SetEventNotificationMode(JVMTI_ENV_ARG(jvmti, JVMTI_ENABLE), JVMTI_EVENT_VM_INIT,NULL); 186 JVMTI_ERROR_CHECK("SetEventNotificationMode for VM_INIT returned error", res); 187 188 return JNI_OK; 189 } 190 191 192 193 JNIEXPORT jint JNICALL 194 Java_nsk_jvmti_unit_setNullVMInit_JvmtiTest_check(JNIEnv *env, jclass cls) { 195 check_val(get_env_local(), 77, "env lasts"); 196 set_env_local(0); 197 check_val(get_env_local(), 0, "env reset to zero"); 198 199 check_val(get_thread_local(NULL), 0, "thread check"); 200 201 return iGlobalStatus; 202 } 203 204 #ifdef __cplusplus 205 } 206 #endif