duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: stefank@2314: # include "precompiled.hpp" jprovino@4165: # include "utilities/macros.hpp" jprovino@4165: #if INCLUDE_JVMTI stefank@2314: # include "prims/jvmtiEnter.hpp" stefank@2314: # include "prims/jvmtiRawMonitor.hpp" stefank@2314: # include "prims/jvmtiUtil.hpp" duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: #ifdef JVMTI_TRACE duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: // Error names duke@435: const char* JvmtiUtil::_error_names[] = { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: }; duke@435: duke@435: duke@435: // Event threaded duke@435: const bool JvmtiUtil::_event_threaded[] = { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: }; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: jbyte JvmtiTrace::_event_trace_flags[ duke@435: duke@435: ]; duke@435: duke@435: jint JvmtiTrace::_max_event_index = duke@435: duke@435: ; duke@435: duke@435: // Event names duke@435: const char* JvmtiTrace::_event_names[] = { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: }; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: #endif /*JVMTI_TRACE */ duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: // duke@435: duke@435: names duke@435: const char* duke@435: duke@435: ConstantNames[] = { duke@435: duke@435: duke@435: NULL duke@435: }; duke@435: duke@435: // duke@435: duke@435: value duke@435: jint duke@435: duke@435: ConstantValues[] = { duke@435: duke@435: duke@435: 0 duke@435: }; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: " duke@435: duke@435: ", duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: // Check Event Capabilities duke@435: const bool JvmtiUtil::has_event_capability(jvmtiEvent event_type, const jvmtiCapabilities* capabilities_ptr) { duke@435: switch (event_type) { duke@435: duke@435: duke@435: duke@435: duke@435: case duke@435: duke@435: : duke@435: return capabilities_ptr-> duke@435: duke@435: != 0; duke@435: duke@435: duke@435: duke@435: } duke@435: // if it does not have a capability it is required duke@435: return JNI_TRUE; duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: jbyte JvmtiTrace::_trace_flags[ duke@435: duke@435: ]; duke@435: duke@435: jint JvmtiTrace::_max_function_index = duke@435: duke@435: ; duke@435: duke@435: // Function names duke@435: const char* JvmtiTrace::_function_names[] = { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: }; duke@435: duke@435: // Exclude list duke@435: short JvmtiTrace::_exclude_functions[] = { duke@435: duke@435: duke@435: duke@435: duke@435: 0 duke@435: }; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: extern "C" { duke@435: duke@435: duke@435: duke@435: duke@435: } /* end extern "C" */ duke@435: duke@435: // JVMTI API functions duke@435: struct jvmtiInterface_1_ jvmti duke@435: duke@435: _Interface = { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: }; jprovino@4165: #endif // INCLUDE_JVMTI duke@435: duke@435: duke@435: duke@435: duke@435: jvmti duke@435: duke@435: _ duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: /* duke@435: duke@435: : duke@435: duke@435: duke@435: duke@435: */ duke@435: duke@435: duke@435: duke@435: duke@435: RESERVED */ duke@435: NULL duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: " duke@435: duke@435: " duke@435: duke@435: duke@435: NULL duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: false duke@435: duke@435: duke@435: true duke@435: duke@435: duke@435: duke@435: duke@435: false duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: // duke@435: // functions duke@435: // duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if (this_thread == NULL || !this_thread->is_Java_thread()) { duke@435: duke@435: duke@435: duke@435: duke@435: if (this_thread == NULL || (!this_thread->is_Java_thread() && !this_thread->is_VM_thread())) { duke@435: duke@435: duke@435: if (!this_thread->is_Java_thread()) { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if (trace_flags) { duke@435: duke@435: tty->print_cr("JVMTI [non-attached thread] %s %s", func_name, duke@435: duke@435: JvmtiUtil::error_name(JVMTI_ERROR_UNATTACHED_THREAD)); duke@435: duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_UNATTACHED_THREAD; duke@435: duke@435: } duke@435: duke@435: duke@435: JavaThread* current_thread = (JavaThread*)this_thread; duke@435: duke@435: ThreadInVMfromNative __tiv(current_thread); duke@435: never@3241: VM_ENTRY_BASE(jvmtiError, duke@435: duke@435: , current_thread) duke@435: duke@435: debug_only(VMNativeEntryWrapper __vew;) duke@435: duke@435: duke@435: CautiouslyPreserveExceptionMark __em(this_thread); duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if (jvmti_env->get_capabilities()-> duke@435: duke@435: == 0) { duke@435: duke@435: duke@435: if (trace_flags) { duke@435: tty->print_cr("JVMTI [%s] %s %s", curr_thread_name, func_name, duke@435: JvmtiUtil::error_name(JVMTI_ERROR_MUST_POSSESS_CAPABILITY)); duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: static jvmtiError JNICALL duke@435: duke@435: duke@435: (jvmtiEnv* env duke@435: duke@435: ) { duke@435: duke@435: duke@435: jprovino@4165: #if !INCLUDE_JVMTI duke@435: return JVMTI_ERROR_NOT_AVAILABLE; duke@435: #else duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if(!JvmtiEnv::is_vm_live()) { duke@435: duke@435: duke@435: if (trace_flags) { duke@435: tty->print_cr("JVMTI [-] %s %s", func_name, duke@435: JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE)); duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_WRONG_PHASE; duke@435: } duke@435: duke@435: duke@435: Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if(JvmtiEnv::get_phase()!=JVMTI_PHASE_ONLOAD duke@435: duke@435: && JvmtiEnv::get_phase()!=JVMTI_PHASE_LIVE duke@435: duke@435: ) { duke@435: duke@435: duke@435: if (trace_flags) { duke@435: tty->print_cr("JVMTI [-] %s %s", func_name, duke@435: JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE)); duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_WRONG_PHASE; duke@435: } duke@435: duke@435: duke@435: if(JvmtiEnv::get_phase()!=JVMTI_PHASE_START && JvmtiEnv::get_phase()!=JVMTI_PHASE_LIVE) { duke@435: duke@435: duke@435: if (trace_flags) { duke@435: tty->print_cr("JVMTI [-] %s %s", func_name, duke@435: JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE)); duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_WRONG_PHASE; duke@435: } duke@435: Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: JvmtiEnv* jvmti_env = JvmtiEnv::JvmtiEnv_from_jvmti_env(env); duke@435: if (!jvmti_env->is_valid()) { duke@435: duke@435: duke@435: if (trace_flags) { duke@435: tty->print_cr("JVMTI [%s] %s %s env=%d", curr_thread_name, func_name, duke@435: JvmtiUtil::error_name(JVMTI_ERROR_INVALID_ENVIRONMENT), env); duke@435: } duke@435: duke@435: duke@435: return JVMTI_ERROR_INVALID_ENVIRONMENT; duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: jvmtiError err; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if (Threads::number_of_threads() != 0) { duke@435: Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); duke@435: duke@435: duke@435: duke@435: Thread* this_thread = NULL; duke@435: bool transition; duke@435: if (Threads::number_of_threads() == 0) { duke@435: transition = false; duke@435: } else { duke@435: this_thread = (Thread*)ThreadLocalStorage::thread(); duke@435: transition = ((this_thread != NULL) && !this_thread->is_VM_thread() && !this_thread->is_ConcurrentGC_thread()); duke@435: } duke@435: if (transition) { duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: } else { duke@435: duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: return err; duke@435: duke@435: duke@435: jprovino@4165: #endif // INCLUDE_JVMTI duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: err = jvmti_env-> duke@435: duke@435: ( duke@435: duke@435: ); duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: SafeResourceMark rm; duke@435: jint trace_flags = JvmtiTrace::trace_flags( duke@435: duke@435: ); duke@435: const char *func_name; duke@435: const char *curr_thread_name; duke@435: if (trace_flags) { duke@435: func_name = JvmtiTrace::function_name( duke@435: duke@435: ); duke@435: curr_thread_name = JvmtiTrace::safe_get_current_thread_name(); duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ((trace_flags & JvmtiTrace::SHOW_IN) != 0) { duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ((trace_flags & JvmtiTrace::SHOW_ERROR) != 0) { duke@435: if ((trace_flags & JvmtiTrace::SHOW_IN) == 0) { duke@435: duke@435: duke@435: duke@435: duke@435: } duke@435: tty->print_cr("JVMTI [%s] %s } %s - erroneous arg is duke@435: duke@435: duke@435: ", curr_thread_name, func_name, duke@435: JvmtiUtil::error_name( duke@435: duke@435: ) duke@435: duke@435: ); duke@435: } duke@435: duke@435: duke@435: return duke@435: duke@435: ; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ( err != JVMTI_ERROR_NONE && (trace_flags & JvmtiTrace::SHOW_ERROR) != 0) { duke@435: if ((trace_flags & JvmtiTrace::SHOW_IN) == 0) { duke@435: duke@435: duke@435: } duke@435: tty->print_cr("JVMTI [%s] %s } %s", curr_thread_name, func_name, duke@435: JvmtiUtil::error_name(err)); duke@435: } else if ((trace_flags & JvmtiTrace::SHOW_OUT) != 0) { duke@435: tty->print_cr("JVMTI [%s] %s }", curr_thread_name, func_name); duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: tty->print_cr("JVMTI [%s] %s { duke@435: duke@435: duke@435: duke@435: ", curr_thread_name, func_name duke@435: duke@435: duke@435: duke@435: ); duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ( duke@435: duke@435: == NULL) { duke@435: duke@435: duke@435: JVMTI_ERROR_NULL_POINTER duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: JvmtiRawMonitor *rmonitor = (JvmtiRawMonitor *) duke@435: duke@435: ; duke@435: if (rmonitor == NULL) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_MONITOR duke@435: - raw monitor is NULL duke@435: duke@435: duke@435: } duke@435: if (!rmonitor->is_valid()) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_MONITOR duke@435: - not a raw monitor 0x%x duke@435: , rmonitor duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: oop thread_oop = JNIHandles::resolve_external_guard( duke@435: duke@435: ); duke@435: if (thread_oop == NULL) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_THREAD mikael@4668: - jthread resolved to NULL - jthread = 0x%x duke@435: , duke@435: duke@435: duke@435: } never@1577: if (!thread_oop->is_a(SystemDictionary::Thread_klass())) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_THREAD mikael@4668: - oop is not a thread - jthread = 0x%x duke@435: , duke@435: duke@435: duke@435: } duke@435: java_thread = java_lang_Thread::thread(thread_oop); duke@435: if (java_thread == NULL) { duke@435: duke@435: duke@435: duke@435: JVMTI_ERROR_THREAD_NOT_ALIVE duke@435: mikael@4668: - not a Java thread - jthread = 0x%x duke@435: , duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: JavaThread* java_thread; duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ( duke@435: duke@435: == NULL) { duke@435: java_thread = current_thread; duke@435: } else { duke@435: duke@435: duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if (depth < 0) { duke@435: duke@435: duke@435: JVMTI_ERROR_ILLEGAL_ARGUMENT mikael@4668: - negative depth - jthread = 0x%x duke@435: , duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: oop k_mirror = JNIHandles::resolve_external_guard( duke@435: duke@435: ); duke@435: if (k_mirror == NULL) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_CLASS duke@435: - resolved to NULL - jclass = 0x%x duke@435: , duke@435: duke@435: duke@435: } never@1577: if (!k_mirror->is_a(SystemDictionary::Class_klass())) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_CLASS duke@435: - not a class - jclass = 0x%x duke@435: , duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: if (java_lang_Class::is_primitive(k_mirror)) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_CLASS duke@435: - is a primitive class - jclass = 0x%x duke@435: , duke@435: duke@435: duke@435: } coleenp@4037: Klass* k_oop = java_lang_Class::as_Klass(k_mirror); duke@435: if (k_oop == NULL) { duke@435: duke@435: duke@435: JVMTI_ERROR_INVALID_CLASS coleenp@4037: - no Klass* - jclass = 0x%x duke@435: , duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: coleenp@4037: Method* method_oop = Method::checked_resolve_jmethod_id( duke@435: duke@435: ); duke@435: if (method_oop == NULL) { duke@435: duke@435: JVMTI_ERROR_INVALID_METHODID duke@435: duke@435: duke@435: duke@435: duke@435: } duke@435: duke@435: if (method_oop->is_native()) { duke@435: return JVMTI_ERROR_NATIVE_METHOD; duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: ResourceMark rm_fdesc(current_thread); duke@435: fieldDescriptor fdesc; duke@435: if (!JvmtiEnv::get_field_descriptor(k_oop, duke@435: duke@435: , &fdesc)) { duke@435: duke@435: JVMTI_ERROR_INVALID_FIELDID duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: if ( duke@435: duke@435: < duke@435: duke@435: ) { duke@435: duke@435: duke@435: JVMTI_ERROR_ILLEGAL_ARGUMENT duke@435: duke@435: duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: ='%s' duke@435: duke@435: duke@435: =0x%x duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =0x%x duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =0x%x duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%s duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%s duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , rmonitor->get_name() duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%s duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: JvmtiTrace::safe_get_thread_name(java_thread) duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: depth=%d duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: JvmtiTrace::get_class_name(k_mirror) duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%s.%s duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: method_oop == NULL? "NULL" : method_oop->klass_name()->as_C_string(), duke@435: method_oop == NULL? "NULL" : method_oop->name()->as_C_string() duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: , fdesc.name()->as_C_string() duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%d:%s duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: JvmtiUtil::error_name( duke@435: duke@435: ) duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: JvmtiTrace::event_name( duke@435: duke@435: ) duke@435: duke@435: duke@435: duke@435: JvmtiTrace::enum_name( duke@435: duke@435: ConstantNames, duke@435: duke@435: ConstantValues, duke@435: duke@435: ) duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%d duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%ld duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =0x%zx duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%f duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%c duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =0x%x duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: =%s duke@435: duke@435: duke@435: duke@435: duke@435: , duke@435: duke@435: ? "true" : "false" duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: duke@435: