< prev index next >

test/hotspot/jtreg/vmTestbase/nsk/jvmti/ThreadStart/threadstart002/threadstart002.cpp

Print this page
rev 52185 : [mq]: refactor


 102                         | thr_resume_lock.enter       |
 103                         | thr_resume_lock.notify      |
 104                         | thr_resume_lock.exit        |
 105                         |                             |  ... check next_thread state
 106                         |                             |  thr_resume_lock.exit
 107                         | thr_start_lock.exit         |
 108                                                       | thr_event_lock.exit
 109 
 110 
 111 */
 112 
 113 static void JNICALL
 114 debug_agent(jvmtiEnv* jvmti, JNIEnv* jni, void *p) {
 115     JNIEnv *env = jni;
 116     jint thrStat;
 117     jobject temp;
 118 
 119     /* Notify VMInit callback as well as ThreadStart callback (if any)
 120      * that agent thread has been started
 121      */
 122     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, agent_start_lock))) {
 123         result = STATUS_FAILED;
 124         NSK_COMPLAIN0("[agent] failed to acquire agent_start_lock\n");
 125     }
 126 
 127     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorNotifyAll, jvmti, agent_start_lock))) {
 128         result = STATUS_FAILED;
 129         NSK_COMPLAIN0("[agent] failed to notify about agent_start_lock\n");
 130     }
 131 
 132     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, agent_start_lock))) {
 133         result = STATUS_FAILED;
 134         NSK_COMPLAIN0("[agent] failed to release agent_start_lock\n");
 135     }
 136 
 137     NSK_DISPLAY0(">>> [agent] agent created\n");
 138 
 139     debug_agent_started = JNI_TRUE;
 140 
 141     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, thr_start_lock))) {
 142         result = STATUS_FAILED;
 143         NSK_COMPLAIN0("[agent] failed to enter thr_start_lock\n");
 144     }
 145 
 146     while (terminate_debug_agent != JNI_TRUE) {
 147 
 148         if (next_thread == NULL ) {
 149             /* wait till new thread will be created and started */
 150             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RawMonitorWait, jvmti, thr_start_lock, (jlong)0))) {
 151                 result = STATUS_FAILED;
 152                 NSK_COMPLAIN0("[agent] Failed while waiting thr_start_lock\n");
 153             }
 154         }
 155 
 156         if (next_thread != NULL) {
 157             /* hmm, why NewGlobalRef is called one more time???
 158              * next_thread = NSK_CPP_STUB2(NewGlobalRef, env, next_thread);
 159              */
 160             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(SuspendThread, jvmti, next_thread))) {
 161                 result = STATUS_FAILED;
 162                 NSK_COMPLAIN1("[agent] Failed to suspend thread#%d\n", eventsCount);
 163             }
 164 
 165             NSK_DISPLAY2(">>> [agent] thread#%d %s suspended ...\n", eventsCount, inf.name);
 166 
 167             /* these dummy calls provoke VM to hang */
 168             temp = NSK_CPP_STUB2(NewGlobalRef, env, next_thread);
 169             NSK_CPP_STUB2(DeleteGlobalRef, env, temp);
 170 
 171             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(ResumeThread, jvmti, next_thread))) {
 172                 result = STATUS_FAILED;
 173                 NSK_COMPLAIN1("[agent] Failed to resume thread#%d\n", eventsCount);
 174             }
 175 
 176             NSK_DISPLAY2(">>> [agent] thread#%d %s resumed ...\n", eventsCount, inf.name);
 177 
 178             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetThreadState, jvmti, next_thread, &thrStat))) {
 179                 result = STATUS_FAILED;
 180                 NSK_COMPLAIN1("[agent] Failed to get thread state for thread#%d\n", eventsCount);
 181             }
 182 
 183             NSK_DISPLAY3(">>> [agent] %s threadState=%s (%x)\n",
 184                     inf.name, TranslateState(thrStat), thrStat);
 185 
 186             if (thrStat & JVMTI_THREAD_STATE_SUSPENDED) {
 187                 NSK_COMPLAIN1("[agent] \"%s\" was not resumed\n", inf.name);
 188                 NSK_CPP_STUB2(FatalError, env, "[agent] could not recover");
 189             }
 190 
 191             NSK_CPP_STUB2(DeleteGlobalRef, env, next_thread);
 192             next_thread = NULL;
 193 
 194             /* Notify ThreadStart callback that thread has been resumed */
 195             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti, thr_resume_lock))) {
 196                 NSK_COMPLAIN0("[agent] Failed to acquire thr_resume_lock\n");
 197                 result = STATUS_FAILED;
 198             }
 199 
 200             debug_agent_timed_out = JNI_FALSE;
 201 
 202             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorNotify, jvmti, thr_resume_lock))) {
 203                 NSK_COMPLAIN0("[agent] Failed to notifing about thr_resume_lock\n");
 204                 result = STATUS_FAILED;
 205             }
 206 
 207             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, thr_resume_lock))) {
 208                 NSK_COMPLAIN0("[agent] Failed to release thr_resume_lock\n");
 209                 result = STATUS_FAILED;
 210             }
 211         }
 212     }
 213 
 214     /*
 215      * We don't call RawMonitorExit(thr_start_lock) in the loop so we don't
 216      * lose any notify calls.
 217      */
 218     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti, thr_start_lock))) {
 219         NSK_COMPLAIN0("[agent] Failed to release thr_start_lock\n");
 220         result = STATUS_FAILED;
 221     }
 222 
 223     NSK_DISPLAY0(">>> [agent] done.\n");
 224 }
 225 
 226 void JNICALL ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) {
 227     jint thrStat;
 228     jvmtiPhase phase;
 229 
 230     NSK_DISPLAY0(">>> [ThreadStart hook] start\n");
 231 
 232     /* skip if thread is 'agent thread' */
 233     if (NSK_CPP_STUB3(IsSameObject, env, agent_thread, thread) == JNI_TRUE) {
 234         NSK_DISPLAY0(">>> [ThreadStart hook] skip agent thread\n");
 235         NSK_DISPLAY0(">>> [ThreadStart hook] end\n");
 236         return;
 237     }
 238 
 239     /* wait till agent thread is started
 240      * (otherwise can fail while waiting on thr_resume_thread due to timeout)
 241      */
 242     if (debug_agent_started != JNI_TRUE) {
 243         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti_env, agent_start_lock))) {
 244             NSK_COMPLAIN0("[ThreadStart hook] Failed to acquire agent_start_lock\n");
 245             result = STATUS_FAILED;
 246         }
 247 
 248         while (debug_agent_started != JNI_TRUE) {
 249             NSK_DISPLAY1(">>> [ThreadStart hook] waiting %dms for agent thread to start\n", WAIT_TIME);
 250 
 251             if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RawMonitorWait,
 252                     jvmti_env, agent_start_lock, (jlong)WAIT_TIME))) {
 253                 NSK_COMPLAIN0("[ThreadStart hook] Failed to wait for agent_start_lock\n");
 254                 result = STATUS_FAILED;
 255             }
 256         }
 257 
 258         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti_env, agent_start_lock))) {
 259             NSK_COMPLAIN0("[ThreadStart hook] Failed to release agent_start_lock\n");
 260             result = STATUS_FAILED;
 261         }
 262     }
 263 
 264 
 265     /* get JVMTI phase */
 266     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
 267         NSK_COMPLAIN0("[ThreadStart hook] Failed to get JVMTI phase\n");
 268         result = STATUS_FAILED;
 269     }
 270 
 271     /* Acquire event lock,
 272      * so only one StartThread callback could be proceeded at the time
 273      */
 274     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti_env, thr_event_lock))) {
 275         NSK_COMPLAIN0("[ThreadStart hook] Failed to acquire thr_event_lock\n");
 276         result = STATUS_FAILED;
 277     }
 278 
 279     {
 280         /* Get thread name */
 281         inf.name = (char*) "UNKNOWN";
 282         if (phase == JVMTI_PHASE_LIVE) {
 283             /* GetThreadInfo may only be called during the live phase */
 284             if (!NSK_JVMTI_VERIFY(
 285                     NSK_CPP_STUB3(GetThreadInfo, jvmti_env, thread, &inf))) {
 286                 NSK_COMPLAIN1("[ThreadStart hook] Failed to get thread infor for thread#%d\n", eventsCount);
 287                 result = STATUS_FAILED;
 288             }
 289         }
 290 
 291         NSK_DISPLAY2(">>> [ThreadStart hook] thread#%d: %s\n", eventsCount, inf.name);
 292 
 293         /* Acquire thr_start_lock */
 294         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti_env, thr_start_lock))) {
 295             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to acquire thr_start_lock\n", eventsCount);
 296             result = STATUS_FAILED;
 297         }
 298 
 299             /* Acquire thr_resume_lock before we release thr_start_lock to prevent
 300              * debug agent from notifying us before we are ready.
 301          */
 302         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti_env, thr_resume_lock))) {
 303             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to acquire thr_resume_lock\n", eventsCount);
 304             result = STATUS_FAILED;
 305         }
 306 
 307         /* Store thread */
 308         next_thread = NSK_CPP_STUB2(NewGlobalRef, env, thread);
 309         debug_agent_timed_out = JNI_TRUE;
 310 
 311         /* Notify agent thread about new started thread and let agent thread to work with it */
 312         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorNotify, jvmti_env, thr_start_lock))) {
 313             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to notify about thr_start_lock\n", eventsCount);
 314             result = STATUS_FAILED;
 315         }
 316 
 317         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti_env, thr_start_lock))) {
 318             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to release thr_start_lock\n", eventsCount);
 319             result = STATUS_FAILED;
 320         }
 321 
 322         /* Wait till this started thread will be resumed by agent thread */
 323         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RawMonitorWait,
 324                 jvmti_env, thr_resume_lock, (jlong)WAIT_TIME ))) {
 325             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed while waiting for thr_resume_lock\n", eventsCount);
 326             result = STATUS_FAILED;
 327         }
 328 
 329         if (debug_agent_timed_out == JNI_TRUE) {
 330             NSK_COMPLAIN1("[ThreadStart hook] \"%s\": debug agent timed out\n", inf.name);
 331             NSK_CPP_STUB2(FatalError, env, "[ThreadStart hook] could not recover");
 332         }
 333 
 334         /* Release thr_resume_lock lock */
 335         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti_env, thr_resume_lock))) {
 336             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to release thr_resume_lock\n", eventsCount);
 337             result = STATUS_FAILED;
 338         }
 339 
 340         /* check that thread is not in SUSPENDED state */
 341         if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetThreadState, jvmti_env, thread, &thrStat))) {
 342             NSK_COMPLAIN1("[ThreadStart hook] Failed to get thread state for thread#%d\n", eventsCount);
 343             result = STATUS_FAILED;
 344         }
 345 
 346         NSK_DISPLAY2(">>> [ThreadStart hook] threadState=%s (%x)\n",
 347                 TranslateState(thrStat), thrStat);
 348 
 349         if (thrStat & JVMTI_THREAD_STATE_SUSPENDED) {
 350             NSK_COMPLAIN1("[ThreadStart hook] \"%s\" was self-suspended\n", inf.name);
 351             NSK_CPP_STUB2(FatalError, env, "[ThreadStart hook] could not recover");
 352         }
 353 
 354         eventsCount++;
 355     }
 356 
 357     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti_env, thr_event_lock))) {
 358         NSK_COMPLAIN0("[ThreadStart hook] Failed to release thr_event_lock\n");
 359         result = STATUS_FAILED;
 360     }
 361 
 362     NSK_DISPLAY0(">>> [ThreadStart hook] end\n");
 363 }
 364 
 365 void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) {
 366     jclass cls = NULL;
 367     jmethodID mid = NULL;
 368 
 369     NSK_DISPLAY0(">>> VMInit event: start\n");
 370 
 371     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 372             jvmti_env, JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL))) {
 373         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_THREAD_START\n");
 374         return;
 375     }
 376 
 377     /* Start agent thread */
 378     if (!NSK_VERIFY((cls =
 379             NSK_CPP_STUB2(FindClass, env, "java/lang/Thread")) != NULL)) {
 380         result = STATUS_FAILED;
 381             NSK_COMPLAIN0("TEST FAILED: Cannot start agent thread: FindClass() failed\n");
 382         return;
 383     }
 384 
 385 
 386     if (!NSK_VERIFY((mid =
 387             NSK_CPP_STUB4(GetMethodID, env, cls, "<init>", "()V")) != NULL)) {
 388         result = STATUS_FAILED;
 389             NSK_COMPLAIN0("TEST FAILED: Cannot start agent thread: GetMethodID() failed\n");
 390         return;
 391     }
 392 
 393 
 394     if (!NSK_VERIFY((agent_thread =
 395             NSK_CPP_STUB3(NewObject, env, cls, mid)) != NULL)) {
 396         result = STATUS_FAILED;
 397             NSK_COMPLAIN0("Cannot start agent thread: NewObject() failed\n");
 398         return;
 399     }
 400 
 401     agent_thread = (jthread) NSK_CPP_STUB2(NewGlobalRef, env, agent_thread);
 402     if (agent_thread == NULL) {
 403         result = STATUS_FAILED;
 404         NSK_COMPLAIN0("Cannot create global reference for agent_thread\n");
 405         return;
 406     }
 407 
 408     /*
 409      * Grab agent_start_lock before launching debug_agent to prevent
 410      * debug_agent from notifying us before we are ready.
 411      */
 412 
 413     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorEnter, jvmti_env, agent_start_lock))) {
 414         result = STATUS_FAILED;
 415         NSK_COMPLAIN0("TEST FAILED: failed to enter agent_start_lock\n");
 416     }
 417 
 418     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(RunAgentThread,
 419             jvmti_env, agent_thread, debug_agent, NULL, JVMTI_THREAD_NORM_PRIORITY))) {
 420         result = STATUS_FAILED;
 421         NSK_COMPLAIN0("TEST FAILED: failed to create agent thread\n");
 422     }
 423 
 424     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(RawMonitorWait, jvmti_env, agent_start_lock, (jlong)0))) {
 425         result = STATUS_FAILED;
 426         NSK_COMPLAIN0("TEST FAILED: failed to wait agent_start_lock\n");
 427     }
 428 
 429     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(RawMonitorExit, jvmti_env, agent_start_lock))) {
 430         result = STATUS_FAILED;
 431         NSK_COMPLAIN0("TEST FAILED: failed to exit agent_start_lock\n");
 432     }
 433 
 434     NSK_DISPLAY0(">>> VMInit event: end\n");
 435 }
 436 
 437 void JNICALL VMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) {
 438     NSK_DISPLAY0(">>> VMDeath event\n");
 439 
 440     terminate_debug_agent = JNI_TRUE;
 441 }
 442 
 443 #ifdef STATIC_BUILD
 444 JNIEXPORT jint JNICALL Agent_OnLoad_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 445     return Agent_Initialize(jvm, options, reserved);
 446 }
 447 JNIEXPORT jint JNICALL Agent_OnAttach_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 448     return Agent_Initialize(jvm, options, reserved);
 449 }
 450 JNIEXPORT jint JNI_OnLoad_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 451     return JNI_VERSION_1_8;
 452 }
 453 #endif
 454 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 455 
 456     /* init framework and parse options */
 457     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 458         return JNI_ERR;
 459 
 460     /* create JVMTI environment */
 461     if (!NSK_VERIFY((jvmti =
 462             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) {
 463         NSK_COMPLAIN0("TEST FAILED: failed to create JVMTIEnv\n");
 464         return JNI_ERR;
 465     }
 466 
 467     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPotentialCapabilities, jvmti, &caps))) {
 468         NSK_COMPLAIN0("TEST FAILED: failed to get potential capabilities\n");
 469         return JNI_ERR;
 470     }
 471 
 472     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
 473         NSK_COMPLAIN0("TEST FAILED: failed to add capabilities during agent load\n");
 474         return JNI_ERR;
 475     }
 476 
 477     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities, jvmti, &caps))) {
 478         NSK_COMPLAIN0("TEST FAILED: failed to get capabilities\n");
 479         return JNI_ERR;
 480     }
 481 
 482     if (!caps.can_suspend) {
 483         NSK_DISPLAY0("WARNING: suspend/resume is not implemented\n");
 484     }
 485 
 486     /* create raw monitors */
 487     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_agent_start_lock", &agent_start_lock))) {
 488         NSK_COMPLAIN0("TEST FAILED: failed to create agent_start_lock\n");
 489         return JNI_ERR;
 490     }
 491 
 492     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_thr_event_lock", &thr_event_lock))) {
 493         NSK_COMPLAIN0("TEST FAILED: failed to create thr_event_lock\n");
 494         return JNI_ERR;
 495     }
 496 
 497     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_thr_start_lock", &thr_start_lock))) {
 498         NSK_COMPLAIN0("TEST FAILED: failed to create thr_start_lock\n");
 499         return JNI_ERR;
 500     }
 501 
 502     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(CreateRawMonitor, jvmti, "_thr_resume_lock", &thr_resume_lock))) {
 503         NSK_COMPLAIN0("TEST FAILED: failed to create thr_resume_lock\n");
 504         return JNI_ERR;
 505     }
 506 
 507     callbacks.VMInit = &VMInit;
 508     callbacks.VMDeath = &VMDeath;
 509     callbacks.ThreadStart = &ThreadStart;
 510 
 511     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetEventCallbacks, jvmti, &callbacks, sizeof(callbacks)))) {
 512         NSK_COMPLAIN0("TEST FAILED: failed to set event callbacks\n");
 513         return JNI_ERR;
 514     }
 515 
 516     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 517             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL))) {
 518         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_VM_INIT\n");
 519         return JNI_ERR;
 520     }
 521 
 522     if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
 523             jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL))) {
 524         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_VM_DEATH\n");
 525         return JNI_ERR;
 526     }
 527 
 528     return JNI_OK;
 529 }
 530 
 531 JNIEXPORT jint JNICALL
 532 Java_nsk_jvmti_ThreadStart_threadstart002_check(JNIEnv *env, jclass cls) {
 533     if (eventsCount == 0) {
 534         NSK_COMPLAIN0("None of thread start events!\n");
 535         result = STATUS_FAILED;
 536     }
 537 
 538     NSK_DISPLAY1(">>> total of thread start events: %d\n", eventsCount);
 539 
 540     return result;
 541 }
 542 
 543 }


 102                         | thr_resume_lock.enter       |
 103                         | thr_resume_lock.notify      |
 104                         | thr_resume_lock.exit        |
 105                         |                             |  ... check next_thread state
 106                         |                             |  thr_resume_lock.exit
 107                         | thr_start_lock.exit         |
 108                                                       | thr_event_lock.exit
 109 
 110 
 111 */
 112 
 113 static void JNICALL
 114 debug_agent(jvmtiEnv* jvmti, JNIEnv* jni, void *p) {
 115     JNIEnv *env = jni;
 116     jint thrStat;
 117     jobject temp;
 118 
 119     /* Notify VMInit callback as well as ThreadStart callback (if any)
 120      * that agent thread has been started
 121      */
 122     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(agent_start_lock))) {
 123         result = STATUS_FAILED;
 124         NSK_COMPLAIN0("[agent] failed to acquire agent_start_lock\n");
 125     }
 126 
 127     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorNotifyAll(agent_start_lock))) {
 128         result = STATUS_FAILED;
 129         NSK_COMPLAIN0("[agent] failed to notify about agent_start_lock\n");
 130     }
 131 
 132     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(agent_start_lock))) {
 133         result = STATUS_FAILED;
 134         NSK_COMPLAIN0("[agent] failed to release agent_start_lock\n");
 135     }
 136 
 137     NSK_DISPLAY0(">>> [agent] agent created\n");
 138 
 139     debug_agent_started = JNI_TRUE;
 140 
 141     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(thr_start_lock))) {
 142         result = STATUS_FAILED;
 143         NSK_COMPLAIN0("[agent] failed to enter thr_start_lock\n");
 144     }
 145 
 146     while (terminate_debug_agent != JNI_TRUE) {
 147 
 148         if (next_thread == NULL ) {
 149             /* wait till new thread will be created and started */
 150             if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorWait(thr_start_lock, (jlong)0))) {
 151                 result = STATUS_FAILED;
 152                 NSK_COMPLAIN0("[agent] Failed while waiting thr_start_lock\n");
 153             }
 154         }
 155 
 156         if (next_thread != NULL) {
 157             /* hmm, why NewGlobalRef is called one more time???
 158              * next_thread = env->NewGlobalRef(next_thread);
 159              */
 160             if (!NSK_JVMTI_VERIFY(jvmti->SuspendThread(next_thread))) {
 161                 result = STATUS_FAILED;
 162                 NSK_COMPLAIN1("[agent] Failed to suspend thread#%d\n", eventsCount);
 163             }
 164 
 165             NSK_DISPLAY2(">>> [agent] thread#%d %s suspended ...\n", eventsCount, inf.name);
 166 
 167             /* these dummy calls provoke VM to hang */
 168             temp = env->NewGlobalRef(next_thread);
 169             env->DeleteGlobalRef(temp);
 170 
 171             if (!NSK_JVMTI_VERIFY(jvmti->ResumeThread(next_thread))) {
 172                 result = STATUS_FAILED;
 173                 NSK_COMPLAIN1("[agent] Failed to resume thread#%d\n", eventsCount);
 174             }
 175 
 176             NSK_DISPLAY2(">>> [agent] thread#%d %s resumed ...\n", eventsCount, inf.name);
 177 
 178             if (!NSK_JVMTI_VERIFY(jvmti->GetThreadState(next_thread, &thrStat))) {
 179                 result = STATUS_FAILED;
 180                 NSK_COMPLAIN1("[agent] Failed to get thread state for thread#%d\n", eventsCount);
 181             }
 182 
 183             NSK_DISPLAY3(">>> [agent] %s threadState=%s (%x)\n",
 184                     inf.name, TranslateState(thrStat), thrStat);
 185 
 186             if (thrStat & JVMTI_THREAD_STATE_SUSPENDED) {
 187                 NSK_COMPLAIN1("[agent] \"%s\" was not resumed\n", inf.name);
 188                 env->FatalError("[agent] could not recover");
 189             }
 190 
 191             env->DeleteGlobalRef(next_thread);
 192             next_thread = NULL;
 193 
 194             /* Notify ThreadStart callback that thread has been resumed */
 195             if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(thr_resume_lock))) {
 196                 NSK_COMPLAIN0("[agent] Failed to acquire thr_resume_lock\n");
 197                 result = STATUS_FAILED;
 198             }
 199 
 200             debug_agent_timed_out = JNI_FALSE;
 201 
 202             if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorNotify(thr_resume_lock))) {
 203                 NSK_COMPLAIN0("[agent] Failed to notifing about thr_resume_lock\n");
 204                 result = STATUS_FAILED;
 205             }
 206 
 207             if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(thr_resume_lock))) {
 208                 NSK_COMPLAIN0("[agent] Failed to release thr_resume_lock\n");
 209                 result = STATUS_FAILED;
 210             }
 211         }
 212     }
 213 
 214     /*
 215      * We don't call RawMonitorExit(thr_start_lock) in the loop so we don't
 216      * lose any notify calls.
 217      */
 218     if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(thr_start_lock))) {
 219         NSK_COMPLAIN0("[agent] Failed to release thr_start_lock\n");
 220         result = STATUS_FAILED;
 221     }
 222 
 223     NSK_DISPLAY0(">>> [agent] done.\n");
 224 }
 225 
 226 void JNICALL ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) {
 227     jint thrStat;
 228     jvmtiPhase phase;
 229 
 230     NSK_DISPLAY0(">>> [ThreadStart hook] start\n");
 231 
 232     /* skip if thread is 'agent thread' */
 233     if (env->IsSameObject(agent_thread, thread) == JNI_TRUE) {
 234         NSK_DISPLAY0(">>> [ThreadStart hook] skip agent thread\n");
 235         NSK_DISPLAY0(">>> [ThreadStart hook] end\n");
 236         return;
 237     }
 238 
 239     /* wait till agent thread is started
 240      * (otherwise can fail while waiting on thr_resume_thread due to timeout)
 241      */
 242     if (debug_agent_started != JNI_TRUE) {
 243         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(agent_start_lock))) {
 244             NSK_COMPLAIN0("[ThreadStart hook] Failed to acquire agent_start_lock\n");
 245             result = STATUS_FAILED;
 246         }
 247 
 248         while (debug_agent_started != JNI_TRUE) {
 249             NSK_DISPLAY1(">>> [ThreadStart hook] waiting %dms for agent thread to start\n", WAIT_TIME);
 250 
 251             if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorWait(agent_start_lock, (jlong)WAIT_TIME))) {

 252                 NSK_COMPLAIN0("[ThreadStart hook] Failed to wait for agent_start_lock\n");
 253                 result = STATUS_FAILED;
 254             }
 255         }
 256 
 257         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(agent_start_lock))) {
 258             NSK_COMPLAIN0("[ThreadStart hook] Failed to release agent_start_lock\n");
 259             result = STATUS_FAILED;
 260         }
 261     }
 262 
 263 
 264     /* get JVMTI phase */
 265     if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) {
 266         NSK_COMPLAIN0("[ThreadStart hook] Failed to get JVMTI phase\n");
 267         result = STATUS_FAILED;
 268     }
 269 
 270     /* Acquire event lock,
 271      * so only one StartThread callback could be proceeded at the time
 272      */
 273     if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(thr_event_lock))) {
 274         NSK_COMPLAIN0("[ThreadStart hook] Failed to acquire thr_event_lock\n");
 275         result = STATUS_FAILED;
 276     }
 277 
 278     {
 279         /* Get thread name */
 280         inf.name = (char*) "UNKNOWN";
 281         if (phase == JVMTI_PHASE_LIVE) {
 282             /* GetThreadInfo may only be called during the live phase */
 283             if (!NSK_JVMTI_VERIFY(jvmti_env->GetThreadInfo(thread, &inf))) {

 284                 NSK_COMPLAIN1("[ThreadStart hook] Failed to get thread infor for thread#%d\n", eventsCount);
 285                 result = STATUS_FAILED;
 286             }
 287         }
 288 
 289         NSK_DISPLAY2(">>> [ThreadStart hook] thread#%d: %s\n", eventsCount, inf.name);
 290 
 291         /* Acquire thr_start_lock */
 292         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(thr_start_lock))) {
 293             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to acquire thr_start_lock\n", eventsCount);
 294             result = STATUS_FAILED;
 295         }
 296 
 297             /* Acquire thr_resume_lock before we release thr_start_lock to prevent
 298              * debug agent from notifying us before we are ready.
 299          */
 300         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(thr_resume_lock))) {
 301             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to acquire thr_resume_lock\n", eventsCount);
 302             result = STATUS_FAILED;
 303         }
 304 
 305         /* Store thread */
 306         next_thread = env->NewGlobalRef(thread);
 307         debug_agent_timed_out = JNI_TRUE;
 308 
 309         /* Notify agent thread about new started thread and let agent thread to work with it */
 310         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorNotify(thr_start_lock))) {
 311             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to notify about thr_start_lock\n", eventsCount);
 312             result = STATUS_FAILED;
 313         }
 314 
 315         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(thr_start_lock))) {
 316             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to release thr_start_lock\n", eventsCount);
 317             result = STATUS_FAILED;
 318         }
 319 
 320         /* Wait till this started thread will be resumed by agent thread */
 321         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorWait(thr_resume_lock, (jlong)WAIT_TIME ))) {

 322             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed while waiting for thr_resume_lock\n", eventsCount);
 323             result = STATUS_FAILED;
 324         }
 325 
 326         if (debug_agent_timed_out == JNI_TRUE) {
 327             NSK_COMPLAIN1("[ThreadStart hook] \"%s\": debug agent timed out\n", inf.name);
 328             env->FatalError("[ThreadStart hook] could not recover");
 329         }
 330 
 331         /* Release thr_resume_lock lock */
 332         if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(thr_resume_lock))) {
 333             NSK_COMPLAIN1("[ThreadStart hook] thread#%d failed to release thr_resume_lock\n", eventsCount);
 334             result = STATUS_FAILED;
 335         }
 336 
 337         /* check that thread is not in SUSPENDED state */
 338         if (!NSK_JVMTI_VERIFY(jvmti_env->GetThreadState(thread, &thrStat))) {
 339             NSK_COMPLAIN1("[ThreadStart hook] Failed to get thread state for thread#%d\n", eventsCount);
 340             result = STATUS_FAILED;
 341         }
 342 
 343         NSK_DISPLAY2(">>> [ThreadStart hook] threadState=%s (%x)\n",
 344                 TranslateState(thrStat), thrStat);
 345 
 346         if (thrStat & JVMTI_THREAD_STATE_SUSPENDED) {
 347             NSK_COMPLAIN1("[ThreadStart hook] \"%s\" was self-suspended\n", inf.name);
 348             env->FatalError("[ThreadStart hook] could not recover");
 349         }
 350 
 351         eventsCount++;
 352     }
 353 
 354     if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(thr_event_lock))) {
 355         NSK_COMPLAIN0("[ThreadStart hook] Failed to release thr_event_lock\n");
 356         result = STATUS_FAILED;
 357     }
 358 
 359     NSK_DISPLAY0(">>> [ThreadStart hook] end\n");
 360 }
 361 
 362 void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) {
 363     jclass cls = NULL;
 364     jmethodID mid = NULL;
 365 
 366     NSK_DISPLAY0(">>> VMInit event: start\n");
 367 
 368     if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL))) {

 369         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_THREAD_START\n");
 370         return;
 371     }
 372 
 373     /* Start agent thread */
 374     if (!NSK_VERIFY((cls = env->FindClass("java/lang/Thread")) != NULL)) {

 375         result = STATUS_FAILED;
 376             NSK_COMPLAIN0("TEST FAILED: Cannot start agent thread: FindClass() failed\n");
 377         return;
 378     }
 379 
 380 
 381     if (!NSK_VERIFY((mid = env->GetMethodID(cls, "<init>", "()V")) != NULL)) {

 382         result = STATUS_FAILED;
 383             NSK_COMPLAIN0("TEST FAILED: Cannot start agent thread: GetMethodID() failed\n");
 384         return;
 385     }
 386 
 387 
 388     if (!NSK_VERIFY((agent_thread = env->NewObject(cls, mid)) != NULL)) {

 389         result = STATUS_FAILED;
 390             NSK_COMPLAIN0("Cannot start agent thread: NewObject() failed\n");
 391         return;
 392     }
 393 
 394     agent_thread = (jthread) env->NewGlobalRef(agent_thread);
 395     if (agent_thread == NULL) {
 396         result = STATUS_FAILED;
 397         NSK_COMPLAIN0("Cannot create global reference for agent_thread\n");
 398         return;
 399     }
 400 
 401     /*
 402      * Grab agent_start_lock before launching debug_agent to prevent
 403      * debug_agent from notifying us before we are ready.
 404      */
 405 
 406     if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(agent_start_lock))) {
 407         result = STATUS_FAILED;
 408         NSK_COMPLAIN0("TEST FAILED: failed to enter agent_start_lock\n");
 409     }
 410 
 411     if (!NSK_JVMTI_VERIFY(jvmti_env->RunAgentThread(agent_thread, debug_agent, NULL, JVMTI_THREAD_NORM_PRIORITY))) {

 412         result = STATUS_FAILED;
 413         NSK_COMPLAIN0("TEST FAILED: failed to create agent thread\n");
 414     }
 415 
 416     if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorWait(agent_start_lock, (jlong)0))) {
 417         result = STATUS_FAILED;
 418         NSK_COMPLAIN0("TEST FAILED: failed to wait agent_start_lock\n");
 419     }
 420 
 421     if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(agent_start_lock))) {
 422         result = STATUS_FAILED;
 423         NSK_COMPLAIN0("TEST FAILED: failed to exit agent_start_lock\n");
 424     }
 425 
 426     NSK_DISPLAY0(">>> VMInit event: end\n");
 427 }
 428 
 429 void JNICALL VMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) {
 430     NSK_DISPLAY0(">>> VMDeath event\n");
 431 
 432     terminate_debug_agent = JNI_TRUE;
 433 }
 434 
 435 #ifdef STATIC_BUILD
 436 JNIEXPORT jint JNICALL Agent_OnLoad_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 437     return Agent_Initialize(jvm, options, reserved);
 438 }
 439 JNIEXPORT jint JNICALL Agent_OnAttach_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 440     return Agent_Initialize(jvm, options, reserved);
 441 }
 442 JNIEXPORT jint JNI_OnLoad_threadstart002(JavaVM *jvm, char *options, void *reserved) {
 443     return JNI_VERSION_1_8;
 444 }
 445 #endif
 446 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
 447 
 448     /* init framework and parse options */
 449     if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
 450         return JNI_ERR;
 451 
 452     /* create JVMTI environment */
 453     if (!NSK_VERIFY((jvmti =
 454             nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) {
 455         NSK_COMPLAIN0("TEST FAILED: failed to create JVMTIEnv\n");
 456         return JNI_ERR;
 457     }
 458 
 459     if (!NSK_JVMTI_VERIFY(jvmti->GetPotentialCapabilities(&caps))) {
 460         NSK_COMPLAIN0("TEST FAILED: failed to get potential capabilities\n");
 461         return JNI_ERR;
 462     }
 463 
 464     if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
 465         NSK_COMPLAIN0("TEST FAILED: failed to add capabilities during agent load\n");
 466         return JNI_ERR;
 467     }
 468 
 469     if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) {
 470         NSK_COMPLAIN0("TEST FAILED: failed to get capabilities\n");
 471         return JNI_ERR;
 472     }
 473 
 474     if (!caps.can_suspend) {
 475         NSK_DISPLAY0("WARNING: suspend/resume is not implemented\n");
 476     }
 477 
 478     /* create raw monitors */
 479     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_agent_start_lock", &agent_start_lock))) {
 480         NSK_COMPLAIN0("TEST FAILED: failed to create agent_start_lock\n");
 481         return JNI_ERR;
 482     }
 483 
 484     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_thr_event_lock", &thr_event_lock))) {
 485         NSK_COMPLAIN0("TEST FAILED: failed to create thr_event_lock\n");
 486         return JNI_ERR;
 487     }
 488 
 489     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_thr_start_lock", &thr_start_lock))) {
 490         NSK_COMPLAIN0("TEST FAILED: failed to create thr_start_lock\n");
 491         return JNI_ERR;
 492     }
 493 
 494     if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_thr_resume_lock", &thr_resume_lock))) {
 495         NSK_COMPLAIN0("TEST FAILED: failed to create thr_resume_lock\n");
 496         return JNI_ERR;
 497     }
 498 
 499     callbacks.VMInit = &VMInit;
 500     callbacks.VMDeath = &VMDeath;
 501     callbacks.ThreadStart = &ThreadStart;
 502 
 503     if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) {
 504         NSK_COMPLAIN0("TEST FAILED: failed to set event callbacks\n");
 505         return JNI_ERR;
 506     }
 507 
 508     if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL))) {

 509         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_VM_INIT\n");
 510         return JNI_ERR;
 511     }
 512 
 513     if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL))) {

 514         NSK_COMPLAIN0("TEST FAILED: failed to enable JVMTI_EVENT_VM_DEATH\n");
 515         return JNI_ERR;
 516     }
 517 
 518     return JNI_OK;
 519 }
 520 
 521 JNIEXPORT jint JNICALL
 522 Java_nsk_jvmti_ThreadStart_threadstart002_check(JNIEnv *env, jclass cls) {
 523     if (eventsCount == 0) {
 524         NSK_COMPLAIN0("None of thread start events!\n");
 525         result = STATUS_FAILED;
 526     }
 527 
 528     NSK_DISPLAY1(">>> total of thread start events: %d\n", eventsCount);
 529 
 530     return result;
 531 }
 532 
 533 }
< prev index next >