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 "agent_common.h" 28 29 #include "nsk_tools.h" 30 #include "JVMTITools.h" 31 #include "jvmti_tools.h" 32 #include "jni_tools.h" 33 34 extern "C" { 35 36 #define STATUS_FAILED 2 37 #define PASSED 0 38 39 /* tested methods */ 40 #define METH_NUM 4 41 static const char *METHODS[][2] = { 42 {"bpMethod", "()V"}, 43 {"nativeMethod", "()V"}, 44 {"anotherNativeMethod", "(I)V"}, 45 {"runThis", "([Ljava/lang/String;Ljava/io/PrintStream;)I"} 46 }; 47 48 /* event counters for the tested methods and expected numbers 49 of the events */ 50 static volatile long stepEv[][2] = { 51 {0, 1}, 52 {0, 0}, 53 {0, 0}, 54 {0, 1} 55 }; 56 57 static const char *CLASS_SIG = 58 "Lnsk/jvmti/SingleStep/singlestep003;"; 59 60 static volatile jint result = PASSED; 61 static jvmtiEnv *jvmti = NULL; 62 static jvmtiEventCallbacks callbacks; 63 64 static void setBP(jvmtiEnv *jvmti_env, JNIEnv *env, jclass klass) { 65 jmethodID mid; 66 67 if (!NSK_JNI_VERIFY(env, (mid = env->GetMethodID(klass, METHODS[0][0], METHODS[0][1])) != NULL)) 68 env->FatalError("failed to get ID for the java method\n"); 69 70 if (!NSK_JVMTI_VERIFY(jvmti_env->SetBreakpoint(mid, 0))) 71 env->FatalError("failed to set breakpoint\n"); 72 } 73 74 /** callback functions **/ 75 void JNICALL 76 ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) { 77 char *sig, *generic; 78 79 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic))) 80 env->FatalError("failed to obtain a class signature\n"); 81 82 if (sig != NULL && (strcmp(sig, CLASS_SIG) == 0)) { 83 NSK_DISPLAY1( 84 "ClassLoad event received for the class \"%s\"\n" 85 "\tsetting breakpoint ...\n", 86 sig); 87 setBP(jvmti_env, env, klass); 88 } 89 } 90 91 void JNICALL 92 Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method, 93 jlocation loc) { 94 jclass klass; 95 char *sig, *generic; 96 97 NSK_DISPLAY0("Breakpoint event received\n"); 98 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass))) 99 NSK_COMPLAIN0("TEST FAILURE: unable to get method declaring class\n\n"); 100 101 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic))) 102 env->FatalError("Breakpoint: failed to obtain a class signature\n"); 103 104 if (sig != NULL && (strcmp(sig, CLASS_SIG) == 0)) { 105 NSK_DISPLAY1("method declaring class \"%s\"\n\tenabling SingleStep events ...\n", 106 sig); 107 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, thr))) { 108 result = STATUS_FAILED; 109 NSK_COMPLAIN0("TEST FAILURE: cannot enable SingleStep events\n\n"); 110 } 111 } else { 112 result = STATUS_FAILED; 113 NSK_COMPLAIN1("TEST FAILURE: unexpected breakpoint event in method of class \"%s\"\n\n", 114 sig); 115 } 116 } 117 118 void JNICALL 119 SingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 120 jmethodID method, jlocation location) { 121 jclass klass; 122 char *sig, *generic, *methNam, *methSig; 123 int i; 124 125 if (result == STATUS_FAILED) { 126 return; 127 } 128 129 NSK_DISPLAY0(">>>> SingleStep event received\n"); 130 131 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodName(method, &methNam, &methSig, NULL))) { 132 result = STATUS_FAILED; 133 NSK_COMPLAIN0("TEST FAILED: unable to get method name during SingleStep callback\n\n"); 134 return; 135 } 136 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass))) { 137 result = STATUS_FAILED; 138 NSK_COMPLAIN0("TEST FAILED: unable to get method declaring class during SingleStep callback\n\n"); 139 return; 140 } 141 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic))) { 142 result = STATUS_FAILED; 143 NSK_COMPLAIN0("TEST FAILED: unable to obtain a class signature during SingleStep callback\n\n"); 144 return; 145 } 146 147 if (sig != NULL) { 148 if (stepEv[METH_NUM-1][0] == 1) { 149 result = STATUS_FAILED; 150 NSK_COMPLAIN0("TEST FAILED: SingleStep event received after disabling the event generation\n\n"); 151 return; 152 } 153 154 for (i=0; i<METH_NUM; i++) { 155 if ((strcmp(methNam,METHODS[i][0]) == 0) && 156 (strcmp(methSig,METHODS[i][1]) == 0) && 157 (strcmp(sig,CLASS_SIG) == 0)) { 158 stepEv[i][0]++; 159 160 if (stepEv[i][1] == 1) { 161 NSK_DISPLAY3( 162 "CHECK PASSED: SingleStep event received for the method:\n" 163 "\t \"%s %s\" of class \"%s\"\n" 164 "\tas expected\n", 165 methNam, methSig, sig); 166 } else { 167 result = STATUS_FAILED; 168 NSK_COMPLAIN3( 169 "TEST FAILED: SingleStep event received for the method:\n" 170 "\t \"%s %s\" of class \"%s\"\n", 171 methNam, methSig, sig); 172 } 173 174 if (i == (METH_NUM-1)) { 175 NSK_DISPLAY0("Disabling the single step event generation\n"); 176 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_SINGLE_STEP, thread))) { 177 result = STATUS_FAILED; 178 NSK_COMPLAIN0("TEST FAILED: cannot disable SingleStep events\n\n"); 179 } 180 } 181 } 182 } 183 } 184 185 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methNam))) { 186 result = STATUS_FAILED; 187 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n"); 188 } 189 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methSig))) { 190 result = STATUS_FAILED; 191 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method signature\n\n"); 192 } 193 194 NSK_DISPLAY0("<<<<\n\n"); 195 } 196 /************************/ 197 198 /* dummy method used only to provoke SingleStep events */ 199 JNIEXPORT void JNICALL 200 Java_nsk_jvmti_SingleStep_singlestep003_anotherNativeMethod( 201 JNIEnv *env, jobject obj, jint i) { 202 NSK_DISPLAY0("inside the anotherNativeMethod()\n\n"); 203 } 204 205 /* dummy method used only to provoke SingleStep events */ 206 JNIEXPORT void JNICALL 207 Java_nsk_jvmti_SingleStep_singlestep003_nativeMethod( 208 JNIEnv *env, jobject obj) { 209 jint i = 0; 210 211 NSK_DISPLAY0("inside the nativeMethod()\n\n"); 212 i++; 213 214 Java_nsk_jvmti_SingleStep_singlestep003_anotherNativeMethod(env, obj, i); 215 } 216 217 JNIEXPORT jint JNICALL 218 Java_nsk_jvmti_SingleStep_singlestep003_check( 219 JNIEnv *env, jobject obj) { 220 int i; 221 222 for (i=0; i<METH_NUM; i++) 223 if (stepEv[i][0] == 0) { 224 if (stepEv[i][1] == 0) { 225 NSK_DISPLAY1("CHECK PASSED: no SingleStep events for the method \"%s\" as expected\n\n", 226 METHODS[i][0]); 227 } 228 else { 229 result = STATUS_FAILED; 230 NSK_COMPLAIN1("TEST FAILED: no SingleStep events for the method \"%s\"\n\n", 231 METHODS[i][0]); 232 } 233 } 234 235 return result; 236 } 237 238 #ifdef STATIC_BUILD 239 JNIEXPORT jint JNICALL Agent_OnLoad_singlestep003(JavaVM *jvm, char *options, void *reserved) { 240 return Agent_Initialize(jvm, options, reserved); 241 } 242 JNIEXPORT jint JNICALL Agent_OnAttach_singlestep003(JavaVM *jvm, char *options, void *reserved) { 243 return Agent_Initialize(jvm, options, reserved); 244 } 245 JNIEXPORT jint JNI_OnLoad_singlestep003(JavaVM *jvm, char *options, void *reserved) { 246 return JNI_VERSION_1_8; 247 } 248 #endif 249 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 250 jvmtiCapabilities caps; 251 252 /* init framework and parse options */ 253 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 254 return JNI_ERR; 255 256 /* create JVMTI environment */ 257 if (!NSK_VERIFY((jvmti = 258 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 259 return JNI_ERR; 260 261 /* add capability to generate compiled method events */ 262 memset(&caps, 0, sizeof(jvmtiCapabilities)); 263 caps.can_generate_breakpoint_events = 1; 264 caps.can_generate_single_step_events = 1; 265 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 266 return JNI_ERR; 267 268 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 269 return JNI_ERR; 270 if (!caps.can_generate_single_step_events) 271 NSK_DISPLAY0("Warning: generation of single step events is not implemented\n"); 272 273 /* set event callback */ 274 NSK_DISPLAY0("setting event callbacks ...\n"); 275 (void) memset(&callbacks, 0, sizeof(callbacks)); 276 callbacks.ClassLoad = &ClassLoad; 277 callbacks.Breakpoint = &Breakpoint; 278 callbacks.SingleStep = &SingleStep; 279 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) 280 return JNI_ERR; 281 282 NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n"); 283 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL))) 284 return JNI_ERR; 285 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL))) 286 return JNI_ERR; 287 NSK_DISPLAY0("enabling the events done\n\n"); 288 289 return JNI_OK; 290 } 291 292 }