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 <stdlib.h> 25 #include <string.h> 26 27 #include "native_thread.h" 28 #include "jni_tools.h" 29 #include "jvmti_tools.h" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 /* ============================================================================= */ 36 37 /* Be careful: do not build shared library which will be linked with different 38 * agent libs while global variables are used 39 * Now the same source is used to build different agent libs, so these 40 * variables are not shared between agents */ 41 42 static jthread agentThread = NULL; 43 static jvmtiStartFunction agentThreadProc = NULL; 44 static void* agentThreadArg = NULL; 45 46 47 typedef enum {NEW, RUNNABLE, WAITING, SUSPENDED, TERMINATED} thread_state_t; 48 49 typedef struct agent_data_t { 50 volatile thread_state_t thread_state; 51 int last_debuggee_status; 52 jrawMonitorID monitor; 53 } agent_data_t; 54 55 static agent_data_t agent_data; 56 57 static jvmtiEnv* jvmti_env = NULL; 58 static JavaVM* jvm = NULL; 59 static JNIEnv* jni_env = NULL; 60 61 static volatile int currentAgentStatus = NSK_STATUS_PASSED; 62 63 /* ============================================================================= */ 64 65 void nsk_jvmti_setFailStatus() { 66 currentAgentStatus = NSK_STATUS_FAILED; 67 } 68 69 int nsk_jvmti_isFailStatus() { 70 return (nsk_jvmti_getStatus() != NSK_STATUS_PASSED); 71 } 72 73 jint nsk_jvmti_getStatus() { 74 return currentAgentStatus; 75 } 76 77 /* ============================================================================= */ 78 static jvmtiError init_agent_data(jvmtiEnv *jvmti_env, agent_data_t *data) { 79 data->thread_state = NEW; 80 data->last_debuggee_status = NSK_STATUS_PASSED; 81 82 return NSK_CPP_STUB3(CreateRawMonitor, jvmti_env, "agent_data_monitor", &data->monitor); 83 } 84 85 /** Reset agent data to prepare for another run. */ 86 void nsk_jvmti_resetAgentData() { 87 rawMonitorEnter(jvmti_env, agent_data.monitor); 88 /* wait for agentThreadWrapper() to finish */ 89 while (agent_data.thread_state != TERMINATED) { 90 rawMonitorWait(jvmti_env, agent_data.monitor, 10); 91 } 92 agent_data.thread_state = NEW; 93 agent_data.last_debuggee_status = NSK_STATUS_PASSED; 94 rawMonitorExit(jvmti_env, agent_data.monitor); 95 } 96 97 static jvmtiError free_agent_data(jvmtiEnv *jvmti_env, agent_data_t *data) { 98 return NSK_CPP_STUB2(DestroyRawMonitor, jvmti_env, data->monitor); 99 } 100 101 /** Create JVMTI environment. */ 102 jvmtiEnv* nsk_jvmti_createJVMTIEnv(JavaVM* javaVM, void* reserved) { 103 jvm = javaVM; 104 if (!NSK_VERIFY( 105 NSK_CPP_STUB3(GetEnv, javaVM, (void **)&jvmti_env, JVMTI_VERSION_1_1) == JNI_OK)) { 106 nsk_jvmti_setFailStatus(); 107 return NULL; 108 } 109 110 if (!NSK_JVMTI_VERIFY(init_agent_data(jvmti_env, &agent_data))) { 111 nsk_jvmti_setFailStatus(); 112 return NULL; 113 } 114 115 return jvmti_env; 116 } 117 118 /** Dispose JVMTI environment */ 119 static int nsk_jvmti_disposeJVMTIEnv(jvmtiEnv* jvmti_env) { 120 if (jvmti_env != NULL) { 121 if (!NSK_JVMTI_VERIFY( 122 NSK_CPP_STUB1(DisposeEnvironment, jvmti_env))) { 123 nsk_jvmti_setFailStatus(); 124 return NSK_FALSE; 125 } 126 127 if (!NSK_JVMTI_VERIFY(free_agent_data(jvmti_env, &agent_data))) { 128 nsk_jvmti_setFailStatus(); 129 return NSK_FALSE; 130 } 131 } 132 return NSK_TRUE; 133 } 134 135 /** Get JNI environment for agent thread. */ 136 JNIEnv* nsk_jvmti_getAgentJNIEnv() { 137 return jni_env; 138 } 139 140 /** Get JVMTI environment for agent */ 141 jvmtiEnv* nsk_jvmti_getAgentJVMTIEnv() { 142 return jvmti_env; 143 } 144 145 /* ============================================================================= */ 146 static void set_agent_thread_state(thread_state_t value) { 147 rawMonitorEnter(jvmti_env, agent_data.monitor); 148 agent_data.thread_state = value; 149 rawMonitorNotify(jvmti_env, agent_data.monitor); 150 rawMonitorExit(jvmti_env, agent_data.monitor); 151 } 152 153 /** Wrapper for user agent thread. */ 154 static void JNICALL 155 agentThreadWrapper(jvmtiEnv* jvmti_env, JNIEnv* agentJNI, void* arg) { 156 jni_env = agentJNI; 157 158 /* run user agent proc */ 159 { 160 set_agent_thread_state(RUNNABLE); 161 162 NSK_TRACE((*agentThreadProc)(jvmti_env, agentJNI, agentThreadArg)); 163 164 set_agent_thread_state(TERMINATED); 165 } 166 167 /* finalize agent thread */ 168 { 169 /* gelete global ref for agent thread */ 170 NSK_CPP_STUB2(DeleteGlobalRef, agentJNI, agentThread); 171 agentThread = NULL; 172 } 173 } 174 175 /** Start wrapper for user agent thread. */ 176 static jthread startAgentThreadWrapper(JNIEnv *jni_env, jvmtiEnv* jvmti_env) { 177 const jint THREAD_PRIORITY = JVMTI_THREAD_MAX_PRIORITY; 178 const char* THREAD_NAME = "JVMTI agent thread"; 179 const char* THREAD_CLASS_NAME = "java/lang/Thread"; 180 const char* THREAD_CTOR_NAME = "<init>"; 181 const char* THREAD_CTOR_SIGNATURE = "(Ljava/lang/String;)V"; 182 183 jobject threadName = NULL; 184 jclass threadClass = NULL; 185 jmethodID threadCtor = NULL; 186 jobject threadObject = NULL; 187 jobject threadGlobalRef = NULL; 188 189 if (!NSK_JNI_VERIFY(jni_env, (threadClass = 190 NSK_CPP_STUB2(FindClass, jni_env, THREAD_CLASS_NAME)) != NULL)) { 191 return NULL; 192 } 193 194 if (!NSK_JNI_VERIFY(jni_env, (threadCtor = 195 NSK_CPP_STUB4(GetMethodID, jni_env, threadClass, THREAD_CTOR_NAME, THREAD_CTOR_SIGNATURE)) != NULL)) 196 return NULL; 197 198 if (!NSK_JNI_VERIFY(jni_env, (threadName = 199 NSK_CPP_STUB2(NewStringUTF, jni_env, THREAD_NAME)) != NULL)) 200 return NULL; 201 202 if (!NSK_JNI_VERIFY(jni_env, (threadObject = 203 NSK_CPP_STUB4(NewObject, jni_env, threadClass, threadCtor, threadName)) != NULL)) 204 return NULL; 205 206 if (!NSK_JNI_VERIFY(jni_env, (threadGlobalRef = 207 NSK_CPP_STUB2(NewGlobalRef, jni_env, threadObject)) != NULL)) { 208 NSK_CPP_STUB2(DeleteLocalRef, jni_env, threadObject); 209 return NULL; 210 } 211 agentThread = (jthread)threadGlobalRef; 212 213 if (!NSK_JVMTI_VERIFY( 214 NSK_CPP_STUB5(RunAgentThread, jvmti_env, agentThread, 215 &agentThreadWrapper, agentThreadArg, THREAD_PRIORITY))) { 216 NSK_CPP_STUB2(DeleteGlobalRef, jni_env, threadGlobalRef); 217 NSK_CPP_STUB2(DeleteLocalRef, jni_env, threadObject); 218 return NULL; 219 } 220 return agentThread; 221 } 222 223 /** Register user agent thread with arg. */ 224 int nsk_jvmti_setAgentProc(jvmtiStartFunction proc, void* arg) { 225 agentThreadProc = proc; 226 agentThreadArg = arg; 227 return NSK_TRUE; 228 } 229 230 /** Get agent thread ref. */ 231 jthread nsk_jvmti_getAgentThread() { 232 return agentThread; 233 } 234 235 /** Run registered user agent thread via wrapper. */ 236 static jthread nsk_jvmti_runAgentThread(JNIEnv *jni_env, jvmtiEnv* jvmti_env) { 237 /* start agent thread wrapper */ 238 jthread thread = startAgentThreadWrapper(jni_env, jvmti_env); 239 if (thread == NULL) { 240 nsk_jvmti_setFailStatus(); 241 return NULL; 242 } 243 244 return thread; 245 } 246 247 /* ============================================================================= */ 248 249 /** Sleep current thread. */ 250 void nsk_jvmti_sleep(jlong timeout) { 251 int seconds = (int)((timeout + 999) / 1000); 252 THREAD_sleep(seconds); 253 } 254 255 /** Sync point called from Java code. */ 256 static jint syncDebuggeeStatus(JNIEnv* jni_env, jvmtiEnv* jvmti_env, jint debuggeeStatus) { 257 jint result = NSK_STATUS_FAILED; 258 259 rawMonitorEnter(jvmti_env, agent_data.monitor); 260 261 /* save last debugee status */ 262 agent_data.last_debuggee_status = debuggeeStatus; 263 264 /* we don't enter if-stmt in second call */ 265 if (agent_data.thread_state == NEW) { 266 if (nsk_jvmti_runAgentThread(jni_env, jvmti_env) == NULL) 267 goto monitor_exit_and_return; 268 269 /* SP2.2-w - wait for agent thread */ 270 while (agent_data.thread_state == NEW) { 271 rawMonitorWait(jvmti_env, agent_data.monitor, 0); 272 } 273 } 274 275 /* wait for sync permit */ 276 /* we don't enter loop in first call */ 277 while (agent_data.thread_state != WAITING && agent_data.thread_state != TERMINATED) { 278 /* SP4.2-w - second wait for agent thread */ 279 rawMonitorWait(jvmti_env, agent_data.monitor, 0); 280 } 281 282 if (agent_data.thread_state != TERMINATED) { 283 agent_data.thread_state = SUSPENDED; 284 /* SP3.2-n - notify to start test */ 285 /* SP6.2-n - notify to end test */ 286 rawMonitorNotify(jvmti_env, agent_data.monitor); 287 } 288 else { 289 NSK_COMPLAIN0("Debuggee status sync aborted because agent thread has finished\n"); 290 goto monitor_exit_and_return; 291 } 292 293 /* update status from debuggee */ 294 if (debuggeeStatus != NSK_STATUS_PASSED) { 295 nsk_jvmti_setFailStatus(); 296 } 297 298 while (agent_data.thread_state == SUSPENDED) { 299 /* SP5.2-w - wait while testing */ 300 /* SP7.2 - wait for agent end */ 301 rawMonitorWait(jvmti_env, agent_data.monitor, 0); 302 } 303 304 agent_data.last_debuggee_status = nsk_jvmti_getStatus(); 305 result = agent_data.last_debuggee_status; 306 307 monitor_exit_and_return: 308 rawMonitorExit(jvmti_env, agent_data.monitor); 309 return result; 310 } 311 312 /** Wait for sync point with Java code. */ 313 int nsk_jvmti_waitForSync(jlong timeout) { 314 static const int inc_timeout = 1000; 315 316 jlong t = 0; 317 int result = NSK_TRUE; 318 319 rawMonitorEnter(jvmti_env, agent_data.monitor); 320 321 agent_data.thread_state = WAITING; 322 323 /* SP2.2-n - notify agent is waiting and wait */ 324 /* SP4.1-n - notify agent is waiting and wait */ 325 rawMonitorNotify(jvmti_env, agent_data.monitor); 326 327 while (agent_data.thread_state == WAITING) { 328 /* SP3.2-w - wait to start test */ 329 /* SP6.2-w - wait to end test */ 330 rawMonitorWait(jvmti_env, agent_data.monitor, inc_timeout); 331 332 if (timeout == 0) continue; 333 334 t += inc_timeout; 335 336 if (t >= timeout) break; 337 } 338 339 if (agent_data.thread_state == WAITING) { 340 NSK_COMPLAIN1("No status sync occured for timeout: %"LL"d ms\n", timeout); 341 nsk_jvmti_setFailStatus(); 342 result = NSK_FALSE; 343 } 344 345 rawMonitorExit(jvmti_env, agent_data.monitor); 346 347 return result; 348 } 349 350 /** Resume java code suspended on sync point. */ 351 int nsk_jvmti_resumeSync() { 352 int result; 353 rawMonitorEnter(jvmti_env, agent_data.monitor); 354 355 if (agent_data.thread_state == SUSPENDED) { 356 result = NSK_TRUE; 357 agent_data.thread_state = RUNNABLE; 358 /* SP5.2-n - notify suspend done */ 359 /* SP7.2-n - notify agent end */ 360 rawMonitorNotify(jvmti_env, agent_data.monitor); 361 } 362 else { 363 NSK_COMPLAIN0("Debuggee was not suspended on status sync\n"); 364 nsk_jvmti_setFailStatus(); 365 result = NSK_FALSE; 366 } 367 368 rawMonitorExit(jvmti_env, agent_data.monitor); 369 return NSK_TRUE; 370 } 371 372 /** Native function for Java code to provide sync point. */ 373 JNIEXPORT jint JNICALL 374 Java_nsk_share_jvmti_DebugeeClass_checkStatus(JNIEnv* jni_env, jclass cls, jint debuggeeStatus) { 375 jint status; 376 NSK_TRACE(status = syncDebuggeeStatus(jni_env, jvmti_env, debuggeeStatus)); 377 return status; 378 } 379 380 /** Native function for Java code to reset agent data. */ 381 JNIEXPORT void JNICALL 382 Java_nsk_share_jvmti_DebugeeClass_resetAgentData(JNIEnv* jni_env, jclass cls) { 383 NSK_TRACE(nsk_jvmti_resetAgentData()); 384 } 385 386 /* ============================================================================= */ 387 388 /** Find loaded class by signature. */ 389 jclass nsk_jvmti_classBySignature(const char signature[]) { 390 jclass* classes = NULL; 391 jint count = 0; 392 jclass foundClass = NULL; 393 int i; 394 395 if (!NSK_VERIFY(signature != NULL)) { 396 nsk_jvmti_setFailStatus(); 397 return NULL; 398 } 399 400 if (!NSK_JVMTI_VERIFY( 401 NSK_CPP_STUB3(GetLoadedClasses, jvmti_env, &count, &classes))) { 402 nsk_jvmti_setFailStatus(); 403 return NULL; 404 } 405 406 for (i = 0; i < count; i++) { 407 char* sig = NULL; 408 char* generic = NULL; 409 410 if (!NSK_JVMTI_VERIFY( 411 NSK_CPP_STUB4(GetClassSignature, jvmti_env, classes[i], &sig, &generic))) { 412 nsk_jvmti_setFailStatus(); 413 break; 414 } 415 416 if (sig != NULL && strcmp(signature, sig) == 0) { 417 foundClass = classes[i]; 418 } 419 420 if (!(NSK_JVMTI_VERIFY( 421 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)sig)) 422 && NSK_JVMTI_VERIFY( 423 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)generic)))) { 424 nsk_jvmti_setFailStatus(); 425 break; 426 } 427 428 if (foundClass != NULL) 429 break; 430 } 431 432 if (!NSK_JVMTI_VERIFY( 433 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)classes))) { 434 nsk_jvmti_setFailStatus(); 435 return NULL; 436 } 437 438 if (!NSK_JNI_VERIFY(jni_env, (foundClass = (jclass) 439 NSK_CPP_STUB2(NewGlobalRef, jni_env, foundClass)) != NULL)) { 440 nsk_jvmti_setFailStatus(); 441 return NULL; 442 } 443 444 return foundClass; 445 } 446 447 /** Find alive thread by name. */ 448 jthread nsk_jvmti_threadByName(const char name[]) { 449 jthread* threads = NULL; 450 jint count = 0; 451 jthread foundThread = NULL; 452 int i; 453 454 if (!NSK_VERIFY(name != NULL)) { 455 nsk_jvmti_setFailStatus(); 456 return NULL; 457 } 458 459 if (!NSK_JVMTI_VERIFY( 460 NSK_CPP_STUB3(GetAllThreads, jvmti_env, &count, &threads))) { 461 nsk_jvmti_setFailStatus(); 462 return NULL; 463 } 464 465 for (i = 0; i < count; i++) { 466 jvmtiThreadInfo info; 467 468 if (!NSK_JVMTI_VERIFY( 469 NSK_CPP_STUB3(GetThreadInfo, jvmti_env, threads[i], &info))) { 470 nsk_jvmti_setFailStatus(); 471 break; 472 } 473 474 if (info.name != NULL && strcmp(name, info.name) == 0) { 475 foundThread = threads[i]; 476 break; 477 } 478 } 479 480 if (!NSK_JVMTI_VERIFY( 481 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)threads))) { 482 nsk_jvmti_setFailStatus(); 483 return NULL; 484 } 485 486 if (!NSK_JNI_VERIFY(jni_env, (foundThread = (jthread) 487 NSK_CPP_STUB2(NewGlobalRef, jni_env, foundThread)) != NULL)) { 488 nsk_jvmti_setFailStatus(); 489 return NULL; 490 } 491 492 return foundThread; 493 } 494 495 496 /* ============================================================================= */ 497 498 /** Add all capabilities for finding line locations. */ 499 int nsk_jvmti_addLocationCapabilities() { 500 jvmtiCapabilities caps; 501 502 memset(&caps, 0, sizeof(caps)); 503 caps.can_get_line_numbers = 1; 504 if (!NSK_JVMTI_VERIFY( 505 NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps))) 506 return NSK_FALSE; 507 508 return NSK_TRUE; 509 } 510 511 /** Add all capabilities for using breakpoints. */ 512 int nsk_jvmti_addBreakpointCapabilities() { 513 jvmtiCapabilities caps; 514 515 if (!nsk_jvmti_addLocationCapabilities()) 516 return NSK_FALSE; 517 518 memset(&caps, 0, sizeof(caps)); 519 caps.can_generate_breakpoint_events = 1; 520 if (!NSK_JVMTI_VERIFY( 521 NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps))) 522 return NSK_FALSE; 523 524 return NSK_TRUE; 525 } 526 527 /** Find line location. */ 528 jlocation nsk_jvmti_getLineLocation(jclass cls, jmethodID method, int line) { 529 jint count = 0; 530 jvmtiLineNumberEntry* table = NULL; 531 jlocation location = NSK_JVMTI_INVALID_JLOCATION; 532 int i; 533 534 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetLineNumberTable, jvmti_env, method, &count, &table))) 535 return NSK_JVMTI_INVALID_JLOCATION; 536 537 for (i = 0; i < count; i++) { 538 if (table[i].line_number == line) { 539 location = table[i].start_location; 540 break; 541 } 542 } 543 544 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)table))) 545 return NSK_JVMTI_INVALID_JLOCATION; 546 547 return location; 548 } 549 550 /** Set breakpoint to a line. */ 551 jlocation nsk_jvmti_setLineBreakpoint(jclass cls, jmethodID method, int line) { 552 jlocation location = NSK_JVMTI_INVALID_JLOCATION; 553 554 if (!NSK_VERIFY((location = 555 nsk_jvmti_getLineLocation(cls, method, line)) != NSK_JVMTI_INVALID_JLOCATION)) 556 return NSK_JVMTI_INVALID_JLOCATION; 557 558 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetBreakpoint, jvmti_env, method, location))) 559 return NSK_JVMTI_INVALID_JLOCATION; 560 561 return location; 562 } 563 564 /** Remove breakpoint from a line. */ 565 jlocation nsk_jvmti_clearLineBreakpoint(jclass cls, jmethodID method, int line) { 566 jlocation location = NSK_JVMTI_INVALID_JLOCATION; 567 568 if (!NSK_VERIFY((location = 569 nsk_jvmti_getLineLocation(cls, method, line)) != NSK_JVMTI_INVALID_JLOCATION)) 570 return NSK_JVMTI_INVALID_JLOCATION; 571 572 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(ClearBreakpoint, jvmti_env, method, location))) 573 return NSK_JVMTI_INVALID_JLOCATION; 574 575 return location; 576 } 577 578 /* ============================================================================= */ 579 580 /** Enable or disable given events. */ 581 int nsk_jvmti_enableEvents(jvmtiEventMode enable, int size, jvmtiEvent list[], jthread thread) { 582 int i; 583 584 for (i = 0; i < size; i++) { 585 if (!NSK_JVMTI_VERIFY( 586 NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, enable, 587 list[i], thread))) { 588 nsk_jvmti_setFailStatus(); 589 return NSK_FALSE; 590 } 591 } 592 return NSK_TRUE; 593 } 594 595 /* ============================================================================= */ 596 597 typedef jint (JNICALL *checkStatus_type)(JNIEnv* jni_env, jclass cls, jint debuggeeStatus); 598 599 static checkStatus_type checkStatus_func = NULL; 600 601 /** 602 * Proxy function to gain sequential access to checkStatus of each agent 603 */ 604 JNIEXPORT jint JNICALL 605 MA_checkStatus(JNIEnv* jni_env, jclass cls, jint debuggeeStatus) { 606 jint status; 607 608 NSK_TRACE(status = syncDebuggeeStatus(jni_env, jvmti_env, debuggeeStatus)); 609 return (*checkStatus_func)(jni_env, cls, status); 610 } 611 612 /** 613 * nativeMethodBind callback: 614 * if needed, redirects checkStatus native method call 615 */ 616 static void JNICALL nativeMethodBind(jvmtiEnv* jvmti_env, JNIEnv *jni_env, 617 jthread thread, jmethodID mid, 618 void* address, void** new_address_ptr) { 619 const char* BIND_CLASS_NAME = "Lnsk/share/jvmti/DebugeeClass;"; 620 const char* BIND_METHOD_NAME = "checkStatus"; 621 const char* BIND_METHOD_SIGNATURE = "(I)I"; 622 623 jvmtiPhase phase; 624 jclass cls; 625 char *class_sig = NULL; 626 char *name = NULL; 627 char *sig = NULL; 628 629 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) { 630 nsk_jvmti_setFailStatus(); 631 return; 632 } 633 634 if (phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE) 635 return; 636 637 if (NSK_JVMTI_VERIFY( 638 NSK_CPP_STUB5(GetMethodName, jvmti_env, mid, &name, &sig, NULL))) { 639 if (strcmp(name, BIND_METHOD_NAME) == 0 && 640 strcmp(sig, BIND_METHOD_SIGNATURE) == 0) { 641 642 if (NSK_JVMTI_VERIFY( 643 NSK_CPP_STUB3(GetMethodDeclaringClass, jvmti_env, mid, &cls)) 644 && NSK_JVMTI_VERIFY( 645 NSK_CPP_STUB4(GetClassSignature, jvmti_env, cls, &class_sig, NULL)) 646 && strcmp(class_sig, BIND_CLASS_NAME) == 0 647 && address != (void*)Java_nsk_share_jvmti_DebugeeClass_checkStatus) { 648 checkStatus_func = (checkStatus_type)address; 649 NSK_TRACE(*new_address_ptr = (void*)MA_checkStatus); 650 } 651 } 652 } 653 654 if (name != NULL) 655 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)name); 656 657 if (sig != NULL) 658 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)sig); 659 660 if (class_sig != NULL) 661 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)class_sig); 662 } 663 664 /** 665 * Initialize multiple agent: 666 * establish processing of nativeMethodBind events 667 */ 668 int nsk_jvmti_init_MA(jvmtiEventCallbacks* callbacks) { 669 670 if (callbacks == NULL) { 671 NSK_COMPLAIN0("callbacks should not be NULL\n"); 672 nsk_jvmti_setFailStatus(); 673 return NSK_FALSE; 674 } 675 676 if (callbacks->NativeMethodBind != NULL) { 677 NSK_COMPLAIN0("callbacks.NativeMethodBind should be NULL\n"); 678 nsk_jvmti_setFailStatus(); 679 return NSK_FALSE; 680 } 681 682 { 683 jvmtiCapabilities caps; 684 memset(&caps, 0, sizeof(caps)); 685 caps.can_generate_native_method_bind_events = 1; 686 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps))) 687 return NSK_FALSE; 688 } 689 690 callbacks->NativeMethodBind = nativeMethodBind; 691 if (!NSK_JVMTI_VERIFY( 692 NSK_CPP_STUB3(SetEventCallbacks, jvmti_env, callbacks, 693 sizeof(jvmtiEventCallbacks)))) 694 return NSK_FALSE; 695 696 if (!NSK_JVMTI_VERIFY( 697 NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, JVMTI_ENABLE, 698 JVMTI_EVENT_NATIVE_METHOD_BIND, NULL))) 699 return NSK_FALSE; 700 701 return NSK_TRUE; 702 } 703 704 /* ============================================================================= */ 705 706 int nsk_jvmti_isOptionalEvent(jvmtiEvent event) { 707 708 return (event == JVMTI_EVENT_EXCEPTION) 709 || (event == JVMTI_EVENT_EXCEPTION_CATCH) 710 || (event == JVMTI_EVENT_SINGLE_STEP) 711 || (event == JVMTI_EVENT_FRAME_POP) 712 || (event == JVMTI_EVENT_BREAKPOINT) 713 || (event == JVMTI_EVENT_FIELD_ACCESS) 714 || (event == JVMTI_EVENT_FIELD_MODIFICATION) 715 || (event == JVMTI_EVENT_METHOD_ENTRY) 716 || (event == JVMTI_EVENT_METHOD_EXIT) 717 || (event == JVMTI_EVENT_NATIVE_METHOD_BIND) 718 || (event == JVMTI_EVENT_COMPILED_METHOD_LOAD) 719 || (event == JVMTI_EVENT_COMPILED_METHOD_UNLOAD) 720 || (event == JVMTI_EVENT_MONITOR_WAIT) 721 || (event == JVMTI_EVENT_MONITOR_WAITED) 722 || (event == JVMTI_EVENT_MONITOR_CONTENDED_ENTER) 723 || (event == JVMTI_EVENT_MONITOR_CONTENDED_ENTERED) 724 || (event == JVMTI_EVENT_GARBAGE_COLLECTION_START) 725 || (event == JVMTI_EVENT_GARBAGE_COLLECTION_FINISH) 726 || (event == JVMTI_EVENT_OBJECT_FREE) 727 || (event == JVMTI_EVENT_VM_OBJECT_ALLOC); 728 } 729 730 /* ============================================================================= */ 731 732 void nsk_jvmti_showPossessedCapabilities(jvmtiEnv *jvmti_env) { 733 734 jvmtiCapabilities caps; 735 736 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities, jvmti_env, &caps))) { 737 return; 738 } 739 740 NSK_DISPLAY0("\n"); 741 NSK_DISPLAY0("Possessed capabilities:\n"); 742 NSK_DISPLAY0("-----------------------\n"); 743 if (caps.can_tag_objects) 744 NSK_DISPLAY0("\tcan_tag_objects\n"); 745 if (caps.can_generate_field_modification_events) 746 NSK_DISPLAY0("\tcan_generate_field_modification_events\n"); 747 if (caps.can_generate_field_access_events) 748 NSK_DISPLAY0("\tcan_generate_field_access_events\n"); 749 if (caps.can_get_bytecodes) 750 NSK_DISPLAY0("\tcan_get_bytecodes\n"); 751 if (caps.can_get_synthetic_attribute) 752 NSK_DISPLAY0("\tcan_get_synthetic_attribute\n"); 753 if (caps.can_get_owned_monitor_info) 754 NSK_DISPLAY0("\tcan_get_owned_monitor_info\n"); 755 if (caps.can_get_current_contended_monitor) 756 NSK_DISPLAY0("\tcan_get_current_contended_monitor\n"); 757 if (caps.can_get_monitor_info) 758 NSK_DISPLAY0("\tcan_get_monitor_info\n"); 759 if (caps.can_pop_frame) 760 NSK_DISPLAY0("\tcan_pop_frame\n"); 761 if (caps.can_redefine_classes) 762 NSK_DISPLAY0("\tcan_redefine_classes\n"); 763 if (caps.can_signal_thread) 764 NSK_DISPLAY0("\tcan_signal_thread\n"); 765 if (caps.can_get_source_file_name) 766 NSK_DISPLAY0("\tcan_get_source_file_name\n"); 767 if (caps.can_get_line_numbers) 768 NSK_DISPLAY0("\tcan_get_line_numbers\n"); 769 if (caps.can_get_source_debug_extension) 770 NSK_DISPLAY0("\tcan_get_source_debug_extension\n"); 771 if (caps.can_access_local_variables) 772 NSK_DISPLAY0("\tcan_access_local_variables\n"); 773 if (caps.can_maintain_original_method_order) 774 NSK_DISPLAY0("\tcan_maintain_original_method_order\n"); 775 if (caps.can_generate_single_step_events) 776 NSK_DISPLAY0("\tcan_generate_single_step_events\n"); 777 if (caps.can_generate_exception_events) 778 NSK_DISPLAY0("\tcan_generate_exception_events\n"); 779 if (caps.can_generate_frame_pop_events) 780 NSK_DISPLAY0("\tcan_generate_frame_pop_events\n"); 781 if (caps.can_generate_breakpoint_events) 782 NSK_DISPLAY0("\tcan_generate_breakpoint_events\n"); 783 if (caps.can_suspend) 784 NSK_DISPLAY0("\tcan_suspend\n"); 785 if (caps.can_get_current_thread_cpu_time) 786 NSK_DISPLAY0("\tcan_get_current_thread_cpu_time\n"); 787 if (caps.can_get_thread_cpu_time) 788 NSK_DISPLAY0("\tcan_get_thread_cpu_time\n"); 789 if (caps.can_generate_method_entry_events) 790 NSK_DISPLAY0("\tcan_generate_method_entry_events\n"); 791 if (caps.can_generate_method_exit_events) 792 NSK_DISPLAY0("\tcan_generate_method_exit_events\n"); 793 if (caps.can_generate_all_class_hook_events) 794 NSK_DISPLAY0("\tcan_generate_all_class_hook_events\n"); 795 if (caps.can_generate_compiled_method_load_events) 796 NSK_DISPLAY0("\tcan_generate_compiled_method_load_events\n"); 797 if (caps.can_generate_monitor_events) 798 NSK_DISPLAY0("\tcan_generate_monitor_events\n"); 799 if (caps.can_generate_vm_object_alloc_events) 800 NSK_DISPLAY0("\tcan_generate_vm_object_alloc_events\n"); 801 if (caps.can_generate_native_method_bind_events) 802 NSK_DISPLAY0("\tcan_generate_native_method_bind_events\n"); 803 if (caps.can_generate_garbage_collection_events) 804 NSK_DISPLAY0("\tcan_generate_garbage_collection_events\n"); 805 if (caps.can_generate_object_free_events) 806 NSK_DISPLAY0("\tcan_generate_object_free_events\n"); 807 808 NSK_DISPLAY0("\n"); 809 } 810 811 /* ============================================================================= */ 812 813 #ifdef __cplusplus 814 } 815 #endif