1 /* 2 * Copyright (c) 2004, 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 <string.h> 25 #include "jvmti.h" 26 #include "agent_common.h" 27 #include "jni_tools.h" 28 #include "jvmti_tools.h" 29 #include "JVMTITools.h" 30 31 extern "C" { 32 33 /* ============================================================================= */ 34 35 /* scaffold objects */ 36 static jvmtiEnv *jvmti = NULL; 37 static jlong timeout = 0; 38 static jrawMonitorID syncLock = NULL; 39 40 /* constant names */ 41 #define STEP_NUMBER 3 42 #define CLASS_NAME "nsk/jvmti/scenarios/events/EM02/em02t011" 43 #define METHOD_NAME "javaMethod" 44 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1) 45 #define NUMBER_OF_INVOCATIONS 1000 46 47 static int eventCount[JVMTI_EVENT_COUNT]; 48 static int newEventCount[JVMTI_EVENT_COUNT]; 49 50 /* ============================================================================= */ 51 52 static void 53 showEventStatistics(int step) { 54 int i; 55 const char* str; 56 int *currentCounts = (step == 1) ? &eventCount[0] : &newEventCount[0]; 57 58 NSK_DISPLAY0("\n"); 59 NSK_DISPLAY1("Event statistics for %d step:\n", step); 60 NSK_DISPLAY0("-----------------------------\n"); 61 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 62 if (currentCounts[i] > 0) { 63 str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL)); 64 NSK_DISPLAY2("%-40s %7d\n", str, currentCounts[i]); 65 } 66 } 67 } 68 69 /* ========================================================================== */ 70 71 int checkEvents(int step) { 72 int i; 73 jvmtiEvent curr; 74 int result = NSK_TRUE; 75 int *currentCounts; 76 int isExpected = 0; 77 78 switch (step) { 79 case 1: 80 currentCounts = &eventCount[0]; 81 break; 82 83 case 2: 84 case 3: 85 currentCounts = &newEventCount[0]; 86 break; 87 88 default: 89 NSK_COMPLAIN1("Unexpected step no: %d\n", step); 90 return NSK_FALSE; 91 } 92 93 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 94 95 curr = (jvmtiEvent) (i + JVMTI_MIN_EVENT_TYPE_VAL); 96 97 switch (step) { 98 case 1: 99 isExpected = ((curr == JVMTI_EVENT_VM_INIT) 100 || (curr == JVMTI_EVENT_BREAKPOINT)); 101 break; 102 103 case 2: 104 isExpected = (curr == JVMTI_EVENT_BREAKPOINT); 105 break; 106 107 case 3: 108 isExpected = (curr == JVMTI_EVENT_VM_DEATH); 109 break; 110 } 111 112 if (isExpected) { 113 if (curr != JVMTI_EVENT_BREAKPOINT) { 114 if (currentCounts[i] < 1) { 115 NSK_COMPLAIN2("Unexpected events number %7d for %s\n\texpected value must be greater than 1\n", 116 currentCounts[i], 117 TranslateEvent(curr)); 118 result = NSK_FALSE; 119 } 120 } else { 121 if (currentCounts[i] != NUMBER_OF_INVOCATIONS) { 122 NSK_COMPLAIN3("Unexpected number of %s events %d, expected value is %d\n", 123 TranslateEvent(curr), 124 currentCounts[i], 125 NUMBER_OF_INVOCATIONS); 126 result = NSK_FALSE; 127 } 128 } 129 130 } else { 131 132 if (currentCounts[i] > 0) { 133 NSK_COMPLAIN2("Unexpected event %s was sent %d times\n", 134 TranslateEvent(curr), 135 currentCounts[i]); 136 result = NSK_FALSE; 137 } 138 } 139 } 140 141 return result; 142 } 143 144 static void 145 changeCount(jvmtiEvent event, int *currentCounts) { 146 147 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(syncLock))) 148 nsk_jvmti_setFailStatus(); 149 150 currentCounts[event - JVMTI_MIN_EVENT_TYPE_VAL]++; 151 152 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(syncLock))) 153 nsk_jvmti_setFailStatus(); 154 155 } 156 157 /* ============================================================================= */ 158 159 /* callbacks */ 160 JNIEXPORT void JNICALL 161 cbVMInit(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread) { 162 changeCount(JVMTI_EVENT_VM_INIT, &eventCount[0]); 163 } 164 165 JNIEXPORT void JNICALL 166 cbVMDeath(jvmtiEnv* jvmti, JNIEnv* jni_env) { 167 changeCount(JVMTI_EVENT_VM_DEATH, &newEventCount[0]); 168 showEventStatistics(STEP_NUMBER); 169 if (!checkEvents(STEP_NUMBER)) 170 nsk_jvmti_setFailStatus(); 171 172 if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) 173 nsk_jvmti_setFailStatus(); 174 175 } 176 177 void JNICALL 178 cbException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 179 jmethodID method, jlocation location, jobject exception, 180 jmethodID catch_method, jlocation catch_location) { 181 182 changeCount(JVMTI_EVENT_EXCEPTION, &eventCount[0]); 183 } 184 185 void JNICALL 186 cbExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 187 jmethodID method, jlocation location, jobject exception) { 188 189 changeCount(JVMTI_EVENT_EXCEPTION_CATCH, &eventCount[0]); 190 } 191 192 void JNICALL 193 cbSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 194 jmethodID method, jlocation location) { 195 196 changeCount(JVMTI_EVENT_SINGLE_STEP, &eventCount[0]); 197 } 198 199 void JNICALL 200 cbFramePop(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 201 jmethodID method, jboolean was_popped_by_exception) { 202 changeCount(JVMTI_EVENT_FRAME_POP, &eventCount[0]); 203 } 204 205 void JNICALL 206 cbBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 207 jmethodID method, jlocation location) { 208 209 changeCount(JVMTI_EVENT_BREAKPOINT, &eventCount[0]); 210 } 211 212 void JNICALL 213 cbNewBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 214 jmethodID method, jlocation location) { 215 216 changeCount(JVMTI_EVENT_BREAKPOINT, &newEventCount[0]); 217 } 218 219 void JNICALL 220 cbFieldAccess(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 221 jmethodID method, jlocation location, jclass field_klass, 222 jobject object, jfieldID field) { 223 224 changeCount(JVMTI_EVENT_FIELD_ACCESS, &eventCount[0]); 225 } 226 227 void JNICALL 228 cbFieldModification(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 229 jmethodID method, jlocation location, jclass field_klass, 230 jobject object, jfieldID field, char signature_type, 231 jvalue new_value) { 232 233 changeCount(JVMTI_EVENT_FIELD_MODIFICATION, &eventCount[0]); 234 } 235 236 void JNICALL 237 cbMethodEntry(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 238 jmethodID method) { 239 240 changeCount(JVMTI_EVENT_METHOD_ENTRY, &eventCount[0]); 241 } 242 243 void JNICALL 244 cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 245 jmethodID method, jboolean was_popped_by_exception, 246 jvalue return_value) { 247 248 changeCount(JVMTI_EVENT_METHOD_EXIT, &eventCount[0]); 249 } 250 251 void JNICALL 252 cbNativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv* jni_env,jthread thread, 253 jmethodID method, void* address, void** new_address_ptr) { 254 changeCount(JVMTI_EVENT_NATIVE_METHOD_BIND, &eventCount[0]); 255 } 256 257 void JNICALL 258 cbMonitorWait(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 259 jobject object, jlong tout) { 260 261 changeCount(JVMTI_EVENT_MONITOR_WAIT, &eventCount[0]); 262 } 263 264 void JNICALL 265 cbMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 266 jobject object, jboolean timed_out) { 267 268 changeCount(JVMTI_EVENT_MONITOR_WAITED, &eventCount[0]); 269 } 270 271 JNIEXPORT void JNICALL 272 cbMonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* jni_env, jthread thread, 273 jobject object) { 274 275 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, &eventCount[0]); 276 } 277 278 void JNICALL 279 cbMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 280 jobject object) { 281 282 changeCount(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, &eventCount[0]); 283 } 284 285 void JNICALL 286 cbCompiledMethodLoad(jvmtiEnv *jvmti_env, jmethodID method, jint code_size, 287 const void* code_addr, jint map_length, 288 const jvmtiAddrLocationMap* map, const void* compile_info) { 289 changeCount(JVMTI_EVENT_COMPILED_METHOD_LOAD, &eventCount[0]); 290 } 291 292 void JNICALL 293 cbCompiledMethodUnload(jvmtiEnv *jvmti_env, jmethodID method, 294 const void* code_addr) { 295 changeCount(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, &eventCount[0]); 296 } 297 298 void JNICALL 299 cbGarbageCollectionStart(jvmtiEnv *jvmti_env) { 300 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_START, &eventCount[0]); 301 } 302 303 void JNICALL 304 cbGarbageCollectionFinish(jvmtiEnv *jvmti_env) { 305 changeCount(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, &eventCount[0]); 306 } 307 308 void JNICALL 309 cbObjectFree(jvmtiEnv *jvmti_env, jlong tag) { 310 311 changeCount(JVMTI_EVENT_OBJECT_FREE, &eventCount[0]); 312 } 313 314 void JNICALL 315 cbVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, 316 jobject object, jclass object_klass, jlong size) { 317 318 changeCount(JVMTI_EVENT_VM_OBJECT_ALLOC, &eventCount[0]); 319 } 320 321 /* ============================================================================= */ 322 323 static int enableEvent(jvmtiEvent event) { 324 325 if (nsk_jvmti_isOptionalEvent(event) 326 && (event != JVMTI_EVENT_BREAKPOINT)) { 327 if (!NSK_JVMTI_VERIFY_CODE(JVMTI_ERROR_MUST_POSSESS_CAPABILITY, 328 jvmti->SetEventNotificationMode(JVMTI_ENABLE, event, NULL))) { 329 NSK_COMPLAIN1("Unexpected error enabling %s\n", 330 TranslateEvent(event)); 331 return NSK_FALSE; 332 } 333 } else { 334 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, event, NULL))) { 335 NSK_COMPLAIN1("Unexpected error enabling %s\n", 336 TranslateEvent(event)); 337 return NSK_FALSE; 338 } 339 } 340 341 return NSK_TRUE; 342 } 343 344 /** 345 * Enable or disable tested events. 346 */ 347 static int enableEventList() { 348 349 int i, result; 350 351 result = enableEvent(JVMTI_EVENT_VM_INIT); 352 353 result = result && enableEvent(JVMTI_EVENT_VM_DEATH); 354 355 /* enabling optional events */ 356 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 357 jvmtiEvent event = (jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL); 358 359 if (nsk_jvmti_isOptionalEvent(event)) 360 result = result && enableEvent(event); 361 } 362 363 if (result == NSK_FALSE) { 364 nsk_jvmti_setFailStatus(); 365 return NSK_FALSE; 366 } 367 368 return NSK_TRUE; 369 } 370 371 /* ============================================================================= */ 372 373 static int 374 setCallBacks(int step) { 375 376 int i; 377 378 jvmtiEventCallbacks eventCallbacks; 379 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 380 381 switch (step) { 382 case 1: 383 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 384 eventCount[i] = 0; 385 } 386 387 eventCallbacks.VMInit = cbVMInit; 388 eventCallbacks.Exception = cbException; 389 eventCallbacks.ExceptionCatch = cbExceptionCatch; 390 eventCallbacks.SingleStep = cbSingleStep; 391 eventCallbacks.FramePop = cbFramePop; 392 eventCallbacks.Breakpoint = cbBreakpoint; 393 eventCallbacks.FieldAccess = cbFieldAccess; 394 eventCallbacks.FieldModification = cbFieldModification; 395 eventCallbacks.MethodEntry = cbMethodEntry; 396 eventCallbacks.MethodExit = cbMethodExit; 397 eventCallbacks.NativeMethodBind = cbNativeMethodBind; 398 eventCallbacks.CompiledMethodLoad = cbCompiledMethodLoad; 399 eventCallbacks.CompiledMethodUnload = cbCompiledMethodUnload; 400 eventCallbacks.MonitorWait = cbMonitorWait; 401 eventCallbacks.MonitorWaited = cbMonitorWaited; 402 eventCallbacks.MonitorContendedEnter = cbMonitorContendedEnter; 403 eventCallbacks.MonitorContendedEntered = cbMonitorContendedEntered; 404 eventCallbacks.GarbageCollectionStart = cbGarbageCollectionStart; 405 eventCallbacks.GarbageCollectionFinish = cbGarbageCollectionFinish; 406 eventCallbacks.ObjectFree = cbObjectFree; 407 eventCallbacks.VMObjectAlloc = cbVMObjectAlloc; 408 break; 409 410 case 2: 411 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 412 newEventCount[i] = 0; 413 } 414 415 eventCallbacks.Breakpoint = cbNewBreakpoint; 416 break; 417 418 case 3: 419 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 420 newEventCount[i] = 0; 421 } 422 423 eventCallbacks.VMDeath = cbVMDeath; 424 break; 425 426 } 427 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 428 return NSK_FALSE; 429 430 return NSK_TRUE; 431 } 432 433 /* ============================================================================= */ 434 435 /** Agent algorithm. */ 436 static void JNICALL 437 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 438 439 int i; 440 jmethodID methodID; 441 jclass cls; 442 443 444 if (!nsk_jvmti_waitForSync(timeout)) 445 return; 446 447 if (!NSK_JNI_VERIFY(agentJNI, (cls = agentJNI->FindClass(CLASS_NAME)) != NULL)) 448 return; 449 450 if (!NSK_JNI_VERIFY(agentJNI, (methodID = 451 agentJNI->GetStaticMethodID(cls, METHOD_NAME, "()I")) != NULL)) 452 return; 453 454 if (!NSK_JVMTI_VERIFY(jvmti->SetBreakpoint(methodID, 0))) 455 return; 456 457 if (!nsk_jvmti_resumeSync()) 458 return; 459 460 for (i = 1; i <= STEP_NUMBER; i++) { 461 462 if (!nsk_jvmti_waitForSync(timeout)) 463 return; 464 465 if (i < STEP_NUMBER) { 466 showEventStatistics(i); 467 if (!checkEvents(i)) 468 nsk_jvmti_setFailStatus(); 469 470 if (!setCallBacks(i + 1)) { 471 return; 472 } 473 } 474 475 if (!nsk_jvmti_resumeSync()) 476 return; 477 } 478 479 } 480 481 /* ============================================================================= */ 482 483 /** Agent library initialization. */ 484 #ifdef STATIC_BUILD 485 JNIEXPORT jint JNICALL Agent_OnLoad_em02t011(JavaVM *jvm, char *options, void *reserved) { 486 return Agent_Initialize(jvm, options, reserved); 487 } 488 JNIEXPORT jint JNICALL Agent_OnAttach_em02t011(JavaVM *jvm, char *options, void *reserved) { 489 return Agent_Initialize(jvm, options, reserved); 490 } 491 JNIEXPORT jint JNI_OnLoad_em02t011(JavaVM *jvm, char *options, void *reserved) { 492 return JNI_VERSION_1_8; 493 } 494 #endif 495 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 496 497 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 498 return JNI_ERR; 499 500 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 501 502 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 503 return JNI_ERR; 504 505 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_syncLock", &syncLock))) { 506 nsk_jvmti_setFailStatus(); 507 return JNI_ERR; 508 } 509 510 { 511 jvmtiCapabilities caps; 512 memset(&caps, 0, sizeof(caps)); 513 514 caps.can_generate_breakpoint_events = 1; 515 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 516 return JNI_ERR; 517 } 518 519 if (!setCallBacks(1)) { 520 return JNI_ERR; 521 } 522 523 if (!enableEventList()) { 524 return JNI_ERR; 525 } 526 527 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 528 return JNI_ERR; 529 530 return JNI_OK; 531 } 532 533 /* ============================================================================= */ 534 535 536 }