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

NMT: Sometimes we skip too many frames

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 17
    • Fix Version/s: tbd
    • Component/s: hotspot
    • Labels:

      Description

      JDK-8261302 introduced a change to NativeCallStack::NativeCallStack() which caused the call to os::get_native_stack() to not be a tail call anymore and hence the "guess-if-its-a-tail-call-or-not" logic was now wrong:

      ```
          // We need to skip the NativeCallStack::NativeCallStack frame if a tail call is NOT used
          // to call os::get_native_stack. A tail call is used if _NMT_NOINLINE_ is not defined
          // (which means this is not a slowdebug build), and we are on 64-bit (except Windows).
          // This is not necessarily a rule, but what has been obvserved to date.
      #if (defined(_NMT_NOINLINE_) || defined(_WINDOWS) || !defined(_LP64) || defined(PPC64))
          // Not a tail call.
          toSkip++;
      #if (defined(_NMT_NOINLINE_) && defined(BSD) && defined(_LP64))
          // Mac OS X slowdebug builds have this odd behavior where NativeCallStack::NativeCallStack
          // appears as two frames, so we need to skip an extra frame.
          toSkip++;
      #endif // Special-case for BSD.
      #endif // Not a tail call.
      ```

      and we were seeing the NativeCallStack::NativeCallStack() frame in the output, not being skipped, which tripped off the associated jtreg test. JDK-8261520 tracks that issue.

      However, what struck me as odd is that not every call stack shows this frame. Some do, some don't. But since the decision to skip frames depends on compile time settings, we either always or never skip. This means that before JDK-8261302, we sometimes skipped where we should not skip.

      I looked at "good" NMT output. And yes, it seems that we sometimes skip too much.

      Examples:

      ```
      [0x00007f6a2439ab71] ModuleEntry::restore_growable_array(Array<ModuleEntry*>*)+0x41
      [0x00007f6a2441c99d] PackageEntryTable::load_archived_entries(Array<PackageEntry*>*)+0x4d
      [0x00007f6a23d59844] ClassLoaderDataShared::serialize(SerializeClosure*)+0xf4
      [0x00007f6a2436a5ea] MetaspaceShared::initialize_shared_spaces()+0x19a
                                   (malloc=2KB type=Module #92)
      ```

      which really should be:

      ```
      [0x00007fc69d73080e] ResourceObj::operator new(unsigned long, ResourceObj::allocation_type, MEMFLAGS)+0x16e
      [0x00007fc69df5d9f1] ModuleEntry::restore_growable_array(Array<ModuleEntry*>*)+0x41
      [0x00007fc69dfdf7ed] PackageEntryTable::load_archived_entries(Array<PackageEntry*>*)+0x4d
      [0x00007fc69d91c844] ClassLoaderDataShared::serialize(SerializeClosure*)+0xf4
                                   (malloc=2KB type=Module #92)
      ```

      or:

      ```
      [0x00007f6a244bc840] SafepointMechanism::initialize()+0x40
      [0x00007f6a2469599f] Threads::create_vm(JavaVMInitArgs*, bool*)+0x17f
      [0x00007f6a240ad951] JNI_CreateJavaVM+0x51
      [0x00007f6a257ad611] JavaMain+0x91
      ```

      missing the last frame, which is os::reserve_memory().


        Attachments

          Issue Links

            Activity

              People

              Assignee:
              stuefe Thomas Stuefe
              Reporter:
              stuefe Thomas Stuefe
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: