changeset 1246:9440a466ee8c

7901456: JMH should print stuck threads before forcefully exiting
author shade
date Thu, 25 Jun 2015 20:58:24 +0300
parents 4863dfc3e61e
children bc6354c5d6ce
files jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedMain.java
diffstat 1 files changed, 36 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedMain.java	Wed Jun 24 13:55:10 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedMain.java	Thu Jun 25 20:58:24 2015 +0300
@@ -29,6 +29,7 @@
 
 import java.io.IOException;
 import java.io.PrintStream;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
@@ -167,6 +168,7 @@
     private static class ShutdownTimeoutThread extends Thread {
         private static final int TIMEOUT = Integer.getInteger("jmh.shutdownTimeout", 30);
         private static final int TIMEOUT_STEP = Integer.getInteger("jmh.shutdownTimeout.step", 5);
+        private static final String LINE_SEPARATOR = System.getProperty("line.separator");
 
         public ShutdownTimeoutThread() {
             setName("JMH-Shutdown-Timeout");
@@ -187,8 +189,7 @@
 
                 waitMore = TimeUnit.SECONDS.toNanos(TIMEOUT) - (System.nanoTime() - start);
 
-                String msg = "<JMH had finished, but forked VM did not exit, are there stray running threads? Waiting " +
-                        TimeUnit.NANOSECONDS.toSeconds(waitMore) + " seconds more...>";
+                String msg = getMessage(waitMore);
 
                 BinaryLinkClient link = linkRef.get();
                 if (link != null) {
@@ -212,6 +213,39 @@
             hangup();
             Runtime.getRuntime().halt(0);
         }
+
+        private String getMessage(long waitMore) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("<JMH had finished, but forked VM did not exit, are there stray running threads? Waiting ")
+                    .append(TimeUnit.NANOSECONDS.toSeconds(waitMore)).append(" seconds more...>");
+            sb.append(LINE_SEPARATOR);
+            sb.append(LINE_SEPARATOR);
+
+            sb.append("Non-finished threads:");
+            sb.append(LINE_SEPARATOR);
+            sb.append(LINE_SEPARATOR);
+
+            for (Map.Entry<Thread, StackTraceElement[]> e : Thread.getAllStackTraces().entrySet()) {
+                Thread thread = e.getKey();
+                StackTraceElement[] els = e.getValue();
+
+                if (thread.isDaemon()) continue;
+                if (!thread.isAlive()) continue;
+
+                sb.append(thread);
+                sb.append(LINE_SEPARATOR);
+
+                for (StackTraceElement el : els) {
+                    sb.append("  at ");
+                    sb.append(el);
+                    sb.append(LINE_SEPARATOR);
+                }
+
+                sb.append(LINE_SEPARATOR);
+            }
+
+            return sb.toString();
+        }
     }
 
 }