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