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

NMT: Sometimes we skip too many frames



    • Enhancement
    • Status: Resolved
    • P4
    • Resolution: Cannot Reproduce
    • 17
    • tbd
    • hotspot


      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.
      #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.
      #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.


      [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)


      [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().


        Issue Links



              stuefe Thomas Stuefe
              stuefe Thomas Stuefe
              0 Vote for this issue
              1 Start watching this issue