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

SIGSEGV happens in getSignature() because of no constant pool lock

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P3 P3
    • None
    • 1.2.2
    • vm-legacy
    • jit
    • sparc
    • solaris, solaris_7

      A licensee reported an issue related JIT(1.2.2_006) in solaris.

      There happens SIGSEGV in their servlet and the core dump is gotten.
      Although they has not sent any test program yet(needs a lot of time
      to extract small portion from their real application) ,
      they send their detail investigation as an alternatives.

      They found out it happened somewhere in the following function,
      getSignature().

      ------>
      char *
      getSignature (JITInfo *jit, unsigned name_type_index)
      {
          union cp_item_type *constant_pool = cbConstantPool(jit->thisClass);
          unsigned type_index = constant_pool[name_type_index].i & 0xffff;
          return constant_pool[type_index].cp;
      }
      <------

        They look into the core file and come to know the below inconsistency.

        The way to get signature depends on whether the constant pool entry
        is resolved or not.

        According to core dump file,
        even though the result of the "if" statement,

           if (CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, methodIndex)) {

        seems to be "true",
        the getSignature(), which should be called on the "false" case, looks
        called instead of fieldsig().

      ----->
      char *
      getMethodSignature (JITInfo *jit, unsigned methodIndex)
      {
          union cp_item_type *constPool = cbConstantPool(jit->thisClass);
          unsigned char *type_table = constPool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;

          (void)resolveCarefully(jit, methodIndex);
          if (CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, methodIndex)) {

              /* Get the signature from the methodblock */
              struct methodblock *mb;
              mb = constPool[methodIndex].mb;
              return fieldsig(&mb->fb);
          } else {

              /* Get the signature indirectly from the CONSTANT_NameAndType item */
              return getSignature(jit, constPool[methodIndex].i & 0xffff);
          }
      }

      <----

      They believe the following senario.

      - When "if" statement is executed by a thread-A, its result is "false.
      - Until the getSignature being called, another thread-B resolves the
        constant pool entry.
      - Although the constant pool entry is resolved, thread-A tries to launch
        getSignature().
        There happens inconsistency between real constant pool status and
        the "false" status of "if" statement which thread-A tested.
        
      They also look into the interpreter part.

      --->
      JNIEXPORT const char * JNICALL
      JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass c, jint cp_index)
      {
          ClassClass *cb = (ClassClass *)DeRef(env, c);
          union cp_item_type *cp = cbConstantPool(cb);
          unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
          switch(type_table[cp_index]) {
          case CONSTANT_InterfaceMethodref:
          case CONSTANT_Methodref: {
             ExecEnv *ee = JNIEnv2EE(env);
             LINKCLASS_LOCK(EE2SysThread(ee)); /*** CONSTANTPOOL IS LOCKED **/
             /* Entry may have been resolved by another thread */
             if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, cp_index)) {
                 unsigned index = cp[cp_index].i; /* value of Fieldref field */
                 unsigned key2 = index & 0xFFFF; /* index to NameAndType */
                 unsigned signature_index = cp[key2].i & 0xFFFF;
                 LINKCLASS_UNLOCK(EE2SysThread(ee));
                 return cp[signature_index].cp;
             }
             LINKCLASS_UNLOCK(EE2SysThread(ee));
             /* FALL THROUGH */
          }
          case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
          case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
              return cp[cp_index].mb->fb.signature;
          default:
              (*env)->FatalError(env, "JVM_GetCPMethodSignatureUTF: illegal constant"
      );
              return NULL; /* Keep lint happy */
          }
      }
      <---

      Just before the similar "if" statement, constant pool is locked in interpreter
      mode.

      So, they believe that JIT also should handle the constant pool exclusively
      by using LOCK or other feature.

      ===============================================================================

            Unassigned Unassigned
            tbaba Tadayuki Baba (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: