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