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 }
|