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