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

ThreadInfo::toString returns String with at most 8 stack frames

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      I tested on Mac and Linux systems. Bug is present in OpenJDK 21, Oracle java 21, and Oracle java 17

      A DESCRIPTION OF THE PROBLEM :
      I am attempting to use ThreadMXBean.dumpAllThreads() to see the states of my threads, but I am only getting 8 stack frames for each thread. The javadoc says that if getThreadInfo() is called without a maxdepth it is the same as Integer.MAX_VALUE. Even if I explicitly pass in Integer.MAX_VALUE I only see 8 stack frames.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See test case.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Should see the entire stack trace for all threads.
      ACTUAL -
      I see at most 8 stack frames. My demo code produces this output:

      "Attach Listener" daemon prio=9 Id=19 RUNNABLE

      "Common-Cleaner" daemon prio=8 Id=18 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@6bdf28bb
      at java.base@21.0.6/jdk.internal.misc.Unsafe.park(Native Method)
      - waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@6bdf28bb
      at java.base@21.0.6/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:269)
      at java.base@21.0.6/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1852)
      at java.base@21.0.6/java.lang.ref.ReferenceQueue.await(ReferenceQueue.java:71)
      at java.base@21.0.6/java.lang.ref.ReferenceQueue.remove0(ReferenceQueue.java:143)
      at java.base@21.0.6/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:218)
      at java.base@21.0.6/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:140)
      at java.base@21.0.6/java.lang.Thread.runWith(Thread.java:1596)
      ...

      "Finalizer" daemon prio=8 Id=10 WAITING on java.lang.ref.NativeReferenceQueue$Lock@7e0babb1
      at java.base@21.0.6/java.lang.Object.wait0(Native Method)
      - waiting on java.lang.ref.NativeReferenceQueue$Lock@7e0babb1
      at java.base@21.0.6/java.lang.Object.wait(Object.java:366)
      at java.base@21.0.6/java.lang.Object.wait(Object.java:339)
      at java.base@21.0.6/java.lang.ref.NativeReferenceQueue.await(NativeReferenceQueue.java:48)
      at java.base@21.0.6/java.lang.ref.ReferenceQueue.remove0(ReferenceQueue.java:158)
      at java.base@21.0.6/java.lang.ref.NativeReferenceQueue.remove(NativeReferenceQueue.java:89)
      at java.base@21.0.6/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:173)

      "Monitor Ctrl-Break" daemon prio=5 Id=20 RUNNABLE
      at java.base@21.0.6/jdk.internal.loader.NativeLibrary.findEntry0(Native Method)
      at java.base@21.0.6/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.find(NativeLibraries.java:312)
      at java.base@21.0.6/jdk.internal.loader.NativeLibraries.find(NativeLibraries.java:103)
      at java.base@21.0.6/java.lang.ClassLoader.findNative(ClassLoader.java:2466)
      at java.base@21.0.6/sun.nio.ch.Net.isExclusiveBindAvailable(Native Method)
      at java.base@21.0.6/sun.nio.ch.Net.<clinit>(Net.java:828)
      at java.base@21.0.6/sun.nio.ch.NioSocketImpl.create(NioSocketImpl.java:466)
      - locked java.lang.Object@6b71769e
      at java.base@21.0.6/java.net.DelegatingSocketImpl.create(DelegatingSocketImpl.java:74)
      ...

      "Notification Thread" daemon prio=9 Id=21 RUNNABLE

      "Reference Handler" daemon prio=10 Id=9 RUNNABLE
      at java.base@21.0.6/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
      at java.base@21.0.6/java.lang.ref.Reference.processPendingReferences(Reference.java:246)
      at java.base@21.0.6/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:208)

      "Signal Dispatcher" daemon prio=9 Id=11 RUNNABLE

      "main" prio=5 Id=1 RUNNABLE
      at java.management@21.0.6/sun.management.ThreadImpl.dumpThreads0(Native Method)
      at java.management@21.0.6/sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:518)
      at app//ThreadDumpBug.printAllThreads(ThreadDumpBug.java:9)
      at app//ThreadDumpBug.printThreads(ThreadDumpBug.java:18)
      at app//ThreadDumpBug.printThreads(ThreadDumpBug.java:16)
      at app//ThreadDumpBug.printThreads(ThreadDumpBug.java:16)
      at app//ThreadDumpBug.printThreads(ThreadDumpBug.java:16)
      at app//ThreadDumpBug.printThreads(ThreadDumpBug.java:16)
      ...


      ---------- BEGIN SOURCE ----------
      import java.io.PrintStream;
      import java.util.Comparator;

      public class ThreadDumpBug {

          public static void printAllThreads(PrintStream pw) {
              java.util.Arrays.stream(
                              java.lang.management.ManagementFactory.getThreadMXBean()
                                      .dumpAllThreads(true, true, Integer.MAX_VALUE)
                      ).sorted(Comparator.comparing(java.lang.management.ThreadInfo::getThreadName))
                      .forEach(pw::print); // already includes newlines, so using print instead of println
          }

          private static void printThreads(int moreFrames, PrintStream pw) {
              if (moreFrames > 0)
                  printThreads(moreFrames - 1 , pw);
              else
                  printAllThreads(pw);
          }

          public static void main(String[] args) {
              printThreads(15, System.out);
          }
      }

      ---------- END SOURCE ----------

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: