Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8268364

jmethod clearing should be done during unloading

    XMLWordPrintable

Details

    • b05

    Description

      jmethodIDs are basically handles of Method*.

      In generated JVMTI functions such as jvmti_GetMethodDeclaringClass, we will first check if a jmethodID is valid (i.e., if it contains a non-NULL Method*). If so, we will dereference the Method*:

      ===================================
      jvmti_GetMethodDeclaringClass(jvmtiEnv* env,
                  jmethodID method,
                  jclass* declaring_class_ptr) {
        if(JvmtiEnv::get_phase(env)!=JVMTI_PHASE_START && JvmtiEnv::get_phase()!=JVMTI_PHASE_LIVE) {
          return JVMTI_ERROR_WRONG_PHASE;
        }
        Thread* this_thread = Thread::current_or_null();
        if (this_thread == NULL || !this_thread->is_Java_thread()) {
          return JVMTI_ERROR_UNATTACHED_THREAD;
        }
        JavaThread* current_thread = this_thread->as_Java_thread();
        MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));
        ThreadInVMfromNative __tiv(current_thread);
        VM_ENTRY_BASE(jvmtiError, jvmti_GetMethodDeclaringClass , current_thread)
        debug_only(VMNativeEntryWrapper __vew;)
        PreserveExceptionMark __em(this_thread);
        JvmtiEnv* jvmti_env = JvmtiEnv::JvmtiEnv_from_jvmti_env(env);
        if (!jvmti_env->is_valid()) {
          return JVMTI_ERROR_INVALID_ENVIRONMENT;
        }
        jvmtiError err;
        Method* checked_method = Method::checked_resolve_jmethod_id(method);
        if (checked_method == NULL) {
            return JVMTI_ERROR_INVALID_METHODID;
        }
        if (declaring_class_ptr == NULL) {
            return JVMTI_ERROR_NULL_POINTER;
        }

        <<<<<<< ZGC can concurrently deallocate the checked_method

        err = jvmti_env->GetMethodDeclaringClass(checked_method, declaring_class_ptr); <<<<< crash
        return err;
      }


      ===================================
       
      This in not compatible with GCs that perform concurrent class deallcation (such as ZGC). If <method> belongs to a class that has been collected (see JDK-8268088), but not yet deallocated, <checked_method> could be non-NULL, but will be concurrently deallocated by ZGC. So by the time we call into jvmti_env->GetMethodDeclaringClass, <checked_method> already points to bad memory.

      Note: ZGC performs metadata deallocation outside of a safepoint. See JDK-8267879 for a case where ClassLoaderData::~ClassLoaderData() is called by ZGC while a safepoint is still in session.

      Attachments

        Issue Links

          Activity

            People

              coleenp Coleen Phillimore
              iklam Ioi Lam
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: