72 j##type val; \ 73 jvmtiError err = jvmti->GetLocal##Type(thr, depth, slot, &val); \ 74 \ 75 printf(" GetLocal%s: %s (%d)\n", #Type, TranslateError(err), err); \ 76 if (err != JVMTI_ERROR_TYPE_MISMATCH) { \ 77 printf(" FAIL: GetLocal%s failed to return JVMTI_ERROR_TYPE_MISMATCH for local %s\n", #Type, exp_type); \ 78 result = STATUS_FAILED; \ 79 } else { \ 80 printf(" GetLocal%s returned JVMTI_ERROR_TYPE_MISMATCH for local %s as expected\n", #Type, exp_type); \ 81 } \ 82 } 83 84 DECL_TEST_FUNC(int, Int); 85 DECL_TEST_FUNC(float, Float); 86 DECL_TEST_FUNC(long, Long); 87 DECL_TEST_FUNC(double, Double); 88 DECL_TEST_FUNC(object, Object); 89 90 DECL_TEST_INV_SLOT_FUNC(int, Int); 91 DECL_TEST_INV_SLOT_FUNC(float, Float); 92 DECL_TEST_INV_SLOT_FUNC(long, Long); 93 DECL_TEST_INV_SLOT_FUNC(double, Double); 94 DECL_TEST_INV_SLOT_FUNC(object, Object); 95 96 DECL_TEST_TYPE_MISMATCH_FUNC(int, Int); 97 DECL_TEST_TYPE_MISMATCH_FUNC(float, Float); 98 DECL_TEST_TYPE_MISMATCH_FUNC(long, Long); 99 DECL_TEST_TYPE_MISMATCH_FUNC(double, Double); 100 DECL_TEST_TYPE_MISMATCH_FUNC(object, Object); 101 102 static void 103 test_local_byte(jthread thr, int depth, int slot) { 104 printf("\n test_local_byte: BEGIN\n\n"); 105 106 test_int(thr, depth, slot, "byte"); 107 test_long_inv_slot(thr, depth, slot, "byte"); 108 test_float(thr, depth, slot, "byte"); 109 test_double_inv_slot(thr, depth, slot, "byte"); 110 test_object_type_mismatch(thr, depth, slot, "byte"); 111 112 printf("\n test_local_byte: END\n\n"); 113 } 114 126 } 127 128 static void 129 test_local_double(jthread thr, int depth, int slot) { 130 printf("\n test_local_double: BEGIN\n\n"); 131 132 test_int(thr, depth, slot, "double"); 133 test_long(thr, depth, slot, "double"); 134 test_float(thr, depth, slot, "double"); 135 test_double(thr, depth, slot, "double"); 136 test_object_type_mismatch(thr, depth, slot, "double"); 137 138 printf("\n test_local_double: END\n\n"); 139 } 140 141 static void 142 test_local_integer(jthread thr, int depth, int slot) { 143 printf("\n test_local_integer: BEGIN\n\n"); 144 145 test_int(thr, depth, slot, "int"); 146 test_long_inv_slot(thr, depth, slot, "int"); 147 test_float(thr, depth, slot, "int"); 148 test_double_inv_slot(thr, depth, slot, "int"); 149 test_object_type_mismatch(thr, depth, slot, "double"); 150 151 printf("\n test_local_integer: END\n\n"); 152 } 153 154 static void 155 test_local_invalid(jthread thr, int depth, int slot) { 156 printf("\n test_local_invalid: BEGIN\n\n"); 157 158 test_int_inv_slot(thr, depth, slot, "invalid"); 159 test_long_inv_slot(thr, depth, slot, "invalid"); 160 test_float_inv_slot(thr, depth, slot, "invalid"); 161 test_double_inv_slot(thr, depth, slot, "invalid"); 162 test_object_inv_slot(thr, depth, slot, "invalid"); 163 164 printf("\n test_local_invalid: END\n\n"); 165 } 166 167 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 168 jint res; 169 jvmtiError err; 170 static jvmtiCapabilities caps; 171 172 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_9); 173 if (res != JNI_OK || jvmti == NULL) { 174 printf("Wrong result of a valid call to GetEnv!\n"); 175 return JNI_ERR; 176 } 177 caps.can_access_local_variables = 1; 178 179 err = jvmti->AddCapabilities(&caps); 180 if (err != JVMTI_ERROR_NONE) { 181 printf("AddCapabilities: unexpected error: %s (%d)\n", TranslateError(err), err); 182 return JNI_ERR; 188 } 189 if (!caps.can_access_local_variables) { 190 printf("Warning: Access to local variables is not implemented\n"); 191 return JNI_ERR; 192 } 193 return JNI_OK; 194 } 195 196 JNIEXPORT jint JNICALL 197 Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { 198 return Agent_Initialize(jvm, options, reserved); 199 } 200 201 JNIEXPORT jint JNICALL 202 Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { 203 return Agent_Initialize(jvm, options, reserved); 204 } 205 206 JNIEXPORT void JNICALL 207 Java_GetLocalVars_testLocals(JNIEnv *env, jclass cls, jobject thread) { 208 static const char* METHOD_NAME = "staticMeth"; 209 static const char* METHOD_SIGN = "(BLjava/lang/Object;DI)I"; 210 static const int Depth = 1; 211 static const int ByteSlot = 0; 212 static const int ObjSlot = 1; 213 static const int DblSlot = 2; 214 static const int IntSlot = 4; 215 static const int InvalidSlot = 5; 216 217 jmethodID mid = NULL; 218 219 if (jvmti == NULL) { 220 printf("JVMTI client was not properly loaded!\n"); 221 result = STATUS_FAILED; 222 return; 223 } 224 225 mid = env->GetStaticMethodID(cls, METHOD_NAME, METHOD_SIGN); 226 if (mid == NULL) { 227 printf("Cannot find Method ID for %s%s\n", METHOD_NAME, METHOD_SIGN); | 72 j##type val; \ 73 jvmtiError err = jvmti->GetLocal##Type(thr, depth, slot, &val); \ 74 \ 75 printf(" GetLocal%s: %s (%d)\n", #Type, TranslateError(err), err); \ 76 if (err != JVMTI_ERROR_TYPE_MISMATCH) { \ 77 printf(" FAIL: GetLocal%s failed to return JVMTI_ERROR_TYPE_MISMATCH for local %s\n", #Type, exp_type); \ 78 result = STATUS_FAILED; \ 79 } else { \ 80 printf(" GetLocal%s returned JVMTI_ERROR_TYPE_MISMATCH for local %s as expected\n", #Type, exp_type); \ 81 } \ 82 } 83 84 DECL_TEST_FUNC(int, Int); 85 DECL_TEST_FUNC(float, Float); 86 DECL_TEST_FUNC(long, Long); 87 DECL_TEST_FUNC(double, Double); 88 DECL_TEST_FUNC(object, Object); 89 90 DECL_TEST_INV_SLOT_FUNC(int, Int); 91 DECL_TEST_INV_SLOT_FUNC(float, Float); 92 93 DECL_TEST_TYPE_MISMATCH_FUNC(int, Int); 94 DECL_TEST_TYPE_MISMATCH_FUNC(float, Float); 95 DECL_TEST_TYPE_MISMATCH_FUNC(long, Long); 96 DECL_TEST_TYPE_MISMATCH_FUNC(double, Double); 97 DECL_TEST_TYPE_MISMATCH_FUNC(object, Object); 98 99 static void 100 test_local_byte(jthread thr, int depth, int slot) { 101 printf("\n test_local_byte: BEGIN\n\n"); 102 103 test_int(thr, depth, slot, "byte"); 104 test_long_inv_slot(thr, depth, slot, "byte"); 105 test_float(thr, depth, slot, "byte"); 106 test_double_inv_slot(thr, depth, slot, "byte"); 107 test_object_type_mismatch(thr, depth, slot, "byte"); 108 109 printf("\n test_local_byte: END\n\n"); 110 } 111 123 } 124 125 static void 126 test_local_double(jthread thr, int depth, int slot) { 127 printf("\n test_local_double: BEGIN\n\n"); 128 129 test_int(thr, depth, slot, "double"); 130 test_long(thr, depth, slot, "double"); 131 test_float(thr, depth, slot, "double"); 132 test_double(thr, depth, slot, "double"); 133 test_object_type_mismatch(thr, depth, slot, "double"); 134 135 printf("\n test_local_double: END\n\n"); 136 } 137 138 static void 139 test_local_integer(jthread thr, int depth, int slot) { 140 printf("\n test_local_integer: BEGIN\n\n"); 141 142 test_int(thr, depth, slot, "int"); 143 test_float(thr, depth, slot, "int"); 144 test_object_type_mismatch(thr, depth, slot, "double"); 145 146 printf("\n test_local_integer: END\n\n"); 147 } 148 149 static void 150 test_local_invalid(jthread thr, int depth, int slot) { 151 printf("\n test_local_invalid: BEGIN\n\n"); 152 153 test_int_inv_slot(thr, depth, slot, "invalid"); 154 test_long_inv_slot(thr, depth, slot, "invalid"); 155 test_float_inv_slot(thr, depth, slot, "invalid"); 156 test_double_inv_slot(thr, depth, slot, "invalid"); 157 158 printf("\n test_local_invalid: END\n\n"); 159 } 160 161 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 162 jint res; 163 jvmtiError err; 164 static jvmtiCapabilities caps; 165 166 res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_9); 167 if (res != JNI_OK || jvmti == NULL) { 168 printf("Wrong result of a valid call to GetEnv!\n"); 169 return JNI_ERR; 170 } 171 caps.can_access_local_variables = 1; 172 173 err = jvmti->AddCapabilities(&caps); 174 if (err != JVMTI_ERROR_NONE) { 175 printf("AddCapabilities: unexpected error: %s (%d)\n", TranslateError(err), err); 176 return JNI_ERR; 182 } 183 if (!caps.can_access_local_variables) { 184 printf("Warning: Access to local variables is not implemented\n"); 185 return JNI_ERR; 186 } 187 return JNI_OK; 188 } 189 190 JNIEXPORT jint JNICALL 191 Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { 192 return Agent_Initialize(jvm, options, reserved); 193 } 194 195 JNIEXPORT jint JNICALL 196 Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { 197 return Agent_Initialize(jvm, options, reserved); 198 } 199 200 JNIEXPORT void JNICALL 201 Java_GetLocalVars_testLocals(JNIEnv *env, jclass cls, jobject thread) { 202 /* 203 * We test the JVMTI GetLocal<Type> for locals of the method: 204 * 205 * int staticMeth(byte byteArg, Object objArg, double dblArg, int intArg) { 206 * testLocals(Thread.currentThread()); 207 * { 208 * int intLoc = 9999; 209 * intArg = intLoc; 210 * } 211 * return intArg; 212 * } 213 */ 214 static const char* METHOD_NAME = "staticMeth"; 215 static const char* METHOD_SIGN = "(BLjava/lang/Object;DI)I"; 216 static const int Depth = 1; 217 static const int ByteSlot = 0; 218 static const int ObjSlot = 1; 219 static const int DblSlot = 2; 220 static const int IntSlot = 4; 221 static const int InvalidSlot = 5; 222 223 jmethodID mid = NULL; 224 225 if (jvmti == NULL) { 226 printf("JVMTI client was not properly loaded!\n"); 227 result = STATUS_FAILED; 228 return; 229 } 230 231 mid = env->GetStaticMethodID(cls, METHOD_NAME, METHOD_SIGN); 232 if (mid == NULL) { 233 printf("Cannot find Method ID for %s%s\n", METHOD_NAME, METHOD_SIGN); |