< prev index next >

src/hotspot/share/services/attachListener.cpp

Print this page




  28 #include "gc/shared/gcVMOperations.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "memory/universe.hpp"
  31 #include "oops/oop.inline.hpp"
  32 #include "oops/typeArrayOop.inline.hpp"
  33 #include "prims/jvmtiExport.hpp"
  34 #include "runtime/arguments.hpp"
  35 #include "runtime/flags/jvmFlag.hpp"
  36 #include "runtime/globals.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/java.hpp"
  39 #include "runtime/javaCalls.hpp"
  40 #include "runtime/os.hpp"
  41 #include "services/attachListener.hpp"
  42 #include "services/diagnosticCommand.hpp"
  43 #include "services/heapDumper.hpp"
  44 #include "services/writeableFlags.hpp"
  45 #include "utilities/debug.hpp"
  46 #include "utilities/formatBuffer.hpp"
  47 
  48 volatile bool AttachListener::_initialized;
  49 
  50 // Implementation of "properties" command.
  51 //
  52 // Invokes VMSupport.serializePropertiesToByteArray to serialize
  53 // the system properties into a byte array.
  54 
  55 static InstanceKlass* load_and_initialize_klass(Symbol* sh, TRAPS) {
  56   Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
  57   InstanceKlass* ik = InstanceKlass::cast(k);
  58   if (ik->should_be_initialized()) {
  59     ik->initialize(CHECK_NULL);
  60   }
  61   return ik;
  62 }
  63 
  64 static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) {
  65   Thread* THREAD = Thread::current();
  66   HandleMark hm;
  67 
  68   // load VMSupport


 355   { "setflag",          set_flag },
 356   { "printflag",        print_flag },
 357   { "jcmd",             jcmd },
 358   { NULL,               NULL }
 359 };
 360 
 361 
 362 
 363 // The Attach Listener threads services a queue. It dequeues an operation
 364 // from the queue, examines the operation name (command), and dispatches
 365 // to the corresponding function to perform the operation.
 366 
 367 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) {
 368   os::set_priority(thread, NearMaxPriority);
 369 
 370   assert(thread == Thread::current(), "Must be");
 371   assert(thread->stack_base() != NULL && thread->stack_size() > 0,
 372          "Should already be setup");
 373 
 374   if (AttachListener::pd_init() != 0) {

 375     return;
 376   }
 377   AttachListener::set_initialized();
 378 
 379   for (;;) {
 380     AttachOperation* op = AttachListener::dequeue();
 381     if (op == NULL) {

 382       return;   // dequeue failed or shutdown
 383     }
 384 
 385     ResourceMark rm;
 386     bufferedStream st;
 387     jint res = JNI_OK;
 388 
 389     // handle special detachall operation
 390     if (strcmp(op->name(), AttachOperation::detachall_operation_name()) == 0) {
 391       AttachListener::detachall();
 392     } else if (!EnableDynamicAgentLoading && strcmp(op->name(), "load") == 0) {
 393       st.print("Dynamic agent loading is not enabled. "
 394                "Use -XX:+EnableDynamicAgentLoading to launch target VM.");
 395       res = JNI_ERR;
 396     } else {
 397       // find the function to dispatch too
 398       AttachOperationFunctionInfo* info = NULL;
 399       for (int i=0; funcs[i].name != NULL; i++) {
 400         const char* name = funcs[i].name;
 401         assert(strlen(name) <= AttachOperation::name_length_max, "operation <= name_length_max");


 405         }
 406       }
 407 
 408       // check for platform dependent attach operation
 409       if (info == NULL) {
 410         info = AttachListener::pd_find_operation(op->name());
 411       }
 412 
 413       if (info != NULL) {
 414         // dispatch to the function that implements this operation
 415         res = (info->func)(op, &st);
 416       } else {
 417         st.print("Operation %s not recognized!", op->name());
 418         res = JNI_ERR;
 419       }
 420     }
 421 
 422     // operation complete - send result and output to client
 423     op->complete(res, &st);
 424   }


 425 }
 426 
 427 bool AttachListener::has_init_error(TRAPS) {
 428   if (HAS_PENDING_EXCEPTION) {
 429     tty->print_cr("Exception in VM (AttachListener::init) : ");
 430     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
 431     tty->cr();
 432 
 433     CLEAR_PENDING_EXCEPTION;
 434 
 435     return true;
 436   } else {
 437     return false;
 438   }
 439 }
 440 
 441 // Starts the Attach Listener thread
 442 void AttachListener::init() {
 443   EXCEPTION_MARK;
 444 
 445   const char thread_name[] = "Attach Listener";
 446   Handle string = java_lang_String::create_from_str(thread_name, THREAD);
 447   if (has_init_error(THREAD)) {

 448     return;
 449   }
 450 
 451   // Initialize thread_oop to put it into the system threadGroup
 452   Handle thread_group (THREAD, Universe::system_thread_group());
 453   Handle thread_oop = JavaCalls::construct_new_instance(SystemDictionary::Thread_klass(),
 454                        vmSymbols::threadgroup_string_void_signature(),
 455                        thread_group,
 456                        string,
 457                        THREAD);
 458   if (has_init_error(THREAD)) {

 459     return;
 460   }
 461 
 462   Klass* group = SystemDictionary::ThreadGroup_klass();
 463   JavaValue result(T_VOID);
 464   JavaCalls::call_special(&result,
 465                         thread_group,
 466                         group,
 467                         vmSymbols::add_method_name(),
 468                         vmSymbols::thread_void_signature(),
 469                         thread_oop,
 470                         THREAD);
 471   if (has_init_error(THREAD)) {

 472     return;
 473   }
 474 
 475   { MutexLocker mu(Threads_lock);
 476     JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry);
 477 
 478     // Check that thread and osthread were created
 479     if (listener_thread == NULL || listener_thread->osthread() == NULL) {
 480       vm_exit_during_initialization("java.lang.OutOfMemoryError",
 481                                     os::native_thread_creation_failed_msg());
 482     }
 483 
 484     java_lang_Thread::set_thread(thread_oop(), listener_thread);
 485     java_lang_Thread::set_daemon(thread_oop());
 486 
 487     listener_thread->set_threadObj(thread_oop());
 488     Threads::add(listener_thread);
 489     Thread::start(listener_thread);
 490   }
 491 }


  28 #include "gc/shared/gcVMOperations.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "memory/universe.hpp"
  31 #include "oops/oop.inline.hpp"
  32 #include "oops/typeArrayOop.inline.hpp"
  33 #include "prims/jvmtiExport.hpp"
  34 #include "runtime/arguments.hpp"
  35 #include "runtime/flags/jvmFlag.hpp"
  36 #include "runtime/globals.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/java.hpp"
  39 #include "runtime/javaCalls.hpp"
  40 #include "runtime/os.hpp"
  41 #include "services/attachListener.hpp"
  42 #include "services/diagnosticCommand.hpp"
  43 #include "services/heapDumper.hpp"
  44 #include "services/writeableFlags.hpp"
  45 #include "utilities/debug.hpp"
  46 #include "utilities/formatBuffer.hpp"
  47 
  48 volatile AttachListenerState AttachListener::_state = AL_NOT_INITIALIZED;
  49 
  50 // Implementation of "properties" command.
  51 //
  52 // Invokes VMSupport.serializePropertiesToByteArray to serialize
  53 // the system properties into a byte array.
  54 
  55 static InstanceKlass* load_and_initialize_klass(Symbol* sh, TRAPS) {
  56   Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
  57   InstanceKlass* ik = InstanceKlass::cast(k);
  58   if (ik->should_be_initialized()) {
  59     ik->initialize(CHECK_NULL);
  60   }
  61   return ik;
  62 }
  63 
  64 static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) {
  65   Thread* THREAD = Thread::current();
  66   HandleMark hm;
  67 
  68   // load VMSupport


 355   { "setflag",          set_flag },
 356   { "printflag",        print_flag },
 357   { "jcmd",             jcmd },
 358   { NULL,               NULL }
 359 };
 360 
 361 
 362 
 363 // The Attach Listener threads services a queue. It dequeues an operation
 364 // from the queue, examines the operation name (command), and dispatches
 365 // to the corresponding function to perform the operation.
 366 
 367 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) {
 368   os::set_priority(thread, NearMaxPriority);
 369 
 370   assert(thread == Thread::current(), "Must be");
 371   assert(thread->stack_base() != NULL && thread->stack_size() > 0,
 372          "Should already be setup");
 373 
 374   if (AttachListener::pd_init() != 0) {
 375     AttachListener::set_state(AL_NOT_INITIALIZED);
 376     return;
 377   }
 378   AttachListener::set_initialized();
 379 
 380   for (;;) {
 381     AttachOperation* op = AttachListener::dequeue();
 382     if (op == NULL) {
 383       AttachListener::set_state(AL_NOT_INITIALIZED);
 384       return;   // dequeue failed or shutdown
 385     }
 386 
 387     ResourceMark rm;
 388     bufferedStream st;
 389     jint res = JNI_OK;
 390 
 391     // handle special detachall operation
 392     if (strcmp(op->name(), AttachOperation::detachall_operation_name()) == 0) {
 393       AttachListener::detachall();
 394     } else if (!EnableDynamicAgentLoading && strcmp(op->name(), "load") == 0) {
 395       st.print("Dynamic agent loading is not enabled. "
 396                "Use -XX:+EnableDynamicAgentLoading to launch target VM.");
 397       res = JNI_ERR;
 398     } else {
 399       // find the function to dispatch too
 400       AttachOperationFunctionInfo* info = NULL;
 401       for (int i=0; funcs[i].name != NULL; i++) {
 402         const char* name = funcs[i].name;
 403         assert(strlen(name) <= AttachOperation::name_length_max, "operation <= name_length_max");


 407         }
 408       }
 409 
 410       // check for platform dependent attach operation
 411       if (info == NULL) {
 412         info = AttachListener::pd_find_operation(op->name());
 413       }
 414 
 415       if (info != NULL) {
 416         // dispatch to the function that implements this operation
 417         res = (info->func)(op, &st);
 418       } else {
 419         st.print("Operation %s not recognized!", op->name());
 420         res = JNI_ERR;
 421       }
 422     }
 423 
 424     // operation complete - send result and output to client
 425     op->complete(res, &st);
 426   }
 427 
 428   ShouldNotReachHere();
 429 }
 430 
 431 bool AttachListener::has_init_error(TRAPS) {
 432   if (HAS_PENDING_EXCEPTION) {
 433     tty->print_cr("Exception in VM (AttachListener::init) : ");
 434     java_lang_Throwable::print(PENDING_EXCEPTION, tty);
 435     tty->cr();
 436 
 437     CLEAR_PENDING_EXCEPTION;
 438 
 439     return true;
 440   } else {
 441     return false;
 442   }
 443 }
 444 
 445 // Starts the Attach Listener thread
 446 void AttachListener::init() {
 447   EXCEPTION_MARK;
 448 
 449   const char thread_name[] = "Attach Listener";
 450   Handle string = java_lang_String::create_from_str(thread_name, THREAD);
 451   if (has_init_error(THREAD)) {
 452     set_state(AL_NOT_INITIALIZED);
 453     return;
 454   }
 455 
 456   // Initialize thread_oop to put it into the system threadGroup
 457   Handle thread_group (THREAD, Universe::system_thread_group());
 458   Handle thread_oop = JavaCalls::construct_new_instance(SystemDictionary::Thread_klass(),
 459                        vmSymbols::threadgroup_string_void_signature(),
 460                        thread_group,
 461                        string,
 462                        THREAD);
 463   if (has_init_error(THREAD)) {
 464     set_state(AL_NOT_INITIALIZED);
 465     return;
 466   }
 467 
 468   Klass* group = SystemDictionary::ThreadGroup_klass();
 469   JavaValue result(T_VOID);
 470   JavaCalls::call_special(&result,
 471                         thread_group,
 472                         group,
 473                         vmSymbols::add_method_name(),
 474                         vmSymbols::thread_void_signature(),
 475                         thread_oop,
 476                         THREAD);
 477   if (has_init_error(THREAD)) {
 478     set_state(AL_NOT_INITIALIZED);
 479     return;
 480   }
 481 
 482   { MutexLocker mu(Threads_lock);
 483     JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry);
 484 
 485     // Check that thread and osthread were created
 486     if (listener_thread == NULL || listener_thread->osthread() == NULL) {
 487       vm_exit_during_initialization("java.lang.OutOfMemoryError",
 488                                     os::native_thread_creation_failed_msg());
 489     }
 490 
 491     java_lang_Thread::set_thread(thread_oop(), listener_thread);
 492     java_lang_Thread::set_daemon(thread_oop());
 493 
 494     listener_thread->set_threadObj(thread_oop());
 495     Threads::add(listener_thread);
 496     Thread::start(listener_thread);
 497   }
 498 }
< prev index next >