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 <stdio.h> 25 #include <string.h> 26 #include "jvmti.h" 27 #include "jni_tools.h" 28 #include "agent_common.h" 29 #include "JVMTITools.h" 30 31 extern "C" { 32 33 34 #define STATUS_PASSED 0 35 #define STATUS_FAILED 2 36 37 static jvmtiEnv *jvmti = NULL; 38 static jint result = STATUS_PASSED; 39 static jboolean printdump = JNI_FALSE; 40 41 void print_LocalVariableEntry(jvmtiLocalVariableEntry *lvt_elem) { 42 printf("\n Var name: %s, slot: %d", lvt_elem->name, lvt_elem->slot); 43 printf(", start_bci: %" LL "d", lvt_elem->start_location); 44 printf(", end_bci: %" LL "d", lvt_elem->start_location + lvt_elem->length); 45 printf(", signature: %s\n", lvt_elem->signature); 46 } 47 48 #ifdef STATIC_BUILD 49 JNIEXPORT jint JNICALL Agent_OnLoad_getlocal004(JavaVM *jvm, char *options, void *reserved) { 50 return Agent_Initialize(jvm, options, reserved); 51 } 52 JNIEXPORT jint JNICALL Agent_OnAttach_getlocal004(JavaVM *jvm, char *options, void *reserved) { 53 return Agent_Initialize(jvm, options, reserved); 54 } 55 JNIEXPORT jint JNI_OnLoad_getlocal004(JavaVM *jvm, char *options, void *reserved) { 56 return JNI_VERSION_1_8; 57 } 58 #endif 59 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 60 jint res; 61 jvmtiError err; 62 static jvmtiCapabilities caps; 63 64 if (options != NULL && strcmp(options, "printdump") == 0) { 65 printdump = JNI_TRUE; 66 } 67 68 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1); 69 if (res != JNI_OK || jvmti == NULL) { 70 printf("Wrong result of a valid call to GetEnv!\n"); 71 return JNI_ERR; 72 } 73 74 err = jvmti->GetPotentialCapabilities(&caps); 75 if (err != JVMTI_ERROR_NONE) { 76 printf("(GetPotentialCapabilities) unexpected error: %s (%d)\n", 77 TranslateError(err), err); 78 return JNI_ERR; 79 } 80 81 err = jvmti->AddCapabilities(&caps); 82 if (err != JVMTI_ERROR_NONE) { 83 printf("(AddCapabilities) unexpected error: %s (%d)\n", 84 TranslateError(err), err); 85 return JNI_ERR; 86 } 87 88 err = jvmti->GetCapabilities(&caps); 89 if (err != JVMTI_ERROR_NONE) { 90 printf("(GetCapabilities) unexpected error: %s (%d)\n", 91 TranslateError(err), err); 92 return JNI_ERR; 93 } 94 95 if (!caps.can_access_local_variables) { 96 printf("Warning: Access to local variables is not implemented\n"); 97 return JNI_ERR; 98 } 99 if (!caps.can_access_local_variables) { 100 printf("Warning: Access to local variables is not implemented\n"); 101 return JNI_ERR; 102 } 103 return JNI_OK; 104 } 105 106 JNIEXPORT void JNICALL 107 Java_nsk_jvmti_unit_GetLocalVariable_getlocal004_getMeth(JNIEnv *env, jclass cls) { 108 jmethodID mid = NULL; 109 110 if (jvmti == NULL) { 111 printf("JVMTI client was not properly loaded!\n"); 112 result = STATUS_FAILED; 113 return; 114 } 115 116 mid = env->GetStaticMethodID(cls, "staticMeth", "(I)I"); 117 if (mid == NULL) { 118 printf("Cannot find Method ID for staticMeth\n"); 119 result = STATUS_FAILED; 120 return; 121 } 122 fflush(stdout); 123 } 124 125 void checkErrorCodeIn(jvmtiError err, jint slot) { 126 if (err != JVMTI_ERROR_NONE) { 127 printf(" FAILURE: JVMTI_ERROR_NONE is expected, slot: %d\n\n", slot); 128 result = STATUS_FAILED; 129 } else { 130 printf(" success: JVMTI_ERROR_NONE as expected, slot: %d\n\n", slot); 131 } 132 } 133 134 void checkErrorCodeOut(jvmtiError err, jint slot) { 135 if (err != JVMTI_ERROR_INVALID_SLOT) { 136 printf(" FAILURE: JVMTI_ERROR_INVALID_SLOT is expected, slot: %d\n\n", slot); 137 result = STATUS_FAILED; 138 } else { 139 printf(" success: JVMTI_ERROR_INVALID_SLOT as expected, slot: %d\n\n", slot); 140 } 141 } 142 143 #define CHECK_ERROR_CODE(scope_no, err, slot) \ 144 if (scope_no == 1) { \ 145 checkErrorCodeOut(err, slot); \ 146 } else { \ 147 checkErrorCodeIn(err, slot); \ 148 } 149 150 JNIEXPORT void JNICALL 151 Java_nsk_jvmti_unit_GetLocalVariable_getlocal004_checkLoc(JNIEnv *env, 152 jclass cls, jthread thr, jint scope_no) { 153 jvmtiError err = JVMTI_ERROR_NONE; 154 jint slot = 0; 155 jint locInt = 0; 156 jlong locLong = 0L; 157 jdouble locDouble = 0.0f; 158 159 if (jvmti == NULL) { 160 return; 161 } 162 printf("\n ----------------- checkLoc: %d -----------------\n\n", scope_no); 163 164 /* Check for slots which has to be available in general */ 165 for (slot = 3; slot < 5; slot++) { 166 err = jvmti->GetLocalInt(thr, 1, slot, &locInt); 167 printf(" GetLocalInt: %s (%d)\n", TranslateError(err), err); 168 CHECK_ERROR_CODE(scope_no, err, slot); 169 170 if (err == JVMTI_ERROR_NONE) { 171 printf(" slot%d: %d\n", slot, locInt); 172 } 173 174 err = jvmti->GetLocalLong(thr, 1, slot, &locLong); 175 printf(" GetLocalLong: %s (%d)\n", TranslateError(err), err); 176 CHECK_ERROR_CODE(scope_no, err, slot); 177 178 err = jvmti->GetLocalDouble(thr, 1, slot, &locDouble); 179 printf(" GetLocalDouble: %s (%d)\n", TranslateError(err), err); 180 CHECK_ERROR_CODE(scope_no, err, slot); 181 } 182 183 /* Slot 5 is special: it's not for 64 bit values! */ 184 slot = 5; { 185 err = jvmti->GetLocalInt(thr, 1, slot, &locInt); 186 printf(" GetLocalInt: %s (%d)\n", TranslateError(err), err); 187 CHECK_ERROR_CODE(scope_no, err, slot); 188 189 if (err == JVMTI_ERROR_NONE) { 190 printf(" slot%d: %d\n", slot, locInt); 191 } 192 193 err = jvmti->GetLocalLong(thr, 1, slot, &locLong); 194 printf(" GetLocalLong: %s (%d)\n", TranslateError(err), err); 195 checkErrorCodeOut(err, slot); 196 197 err = jvmti->GetLocalDouble(thr, 1, slot, &locDouble); 198 printf(" GetLocalDouble: %s (%d)\n", TranslateError(err), err); 199 checkErrorCodeOut(err, slot); 200 } 201 202 /* Check for slots which has to be unavailable in general */ 203 for (slot = 6; slot < 8; slot++) { 204 err = jvmti->GetLocalInt(thr, 1, slot, &locInt); 205 printf(" GetLocalInt: %s (%d)\n", TranslateError(err), err); 206 checkErrorCodeOut(err, slot); 207 208 if (err == JVMTI_ERROR_NONE) { 209 printf(" slot%d: %d\n", slot, locInt); 210 } 211 212 err = jvmti->GetLocalLong(thr, 1, slot, &locLong); 213 printf(" GetLocalLong: %s (%d)\n", TranslateError(err), err); 214 checkErrorCodeOut(err, slot); 215 216 err = jvmti->GetLocalDouble(thr, 1, slot, &locDouble); 217 printf(" GetLocalDouble: %s (%d)\n", TranslateError(err), err); 218 checkErrorCodeOut(err, slot); 219 } 220 221 fflush(stdout); 222 } 223 224 JNIEXPORT jint JNICALL 225 Java_nsk_jvmti_unit_GetLocalVariable_getlocal004_getRes(JNIEnv *env, jclass cls) { 226 return result; 227 } 228 229 }