You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2017/10/31 13:17:23 UTC

[1/2] activemq-artemis git commit: ARTEMIS-1485 ActiveMQTestBase.threadDump should print information about locks and deadlocks

Repository: activemq-artemis
Updated Branches:
  refs/heads/master 60ce40f3a -> 3bdeed80c


ARTEMIS-1485 ActiveMQTestBase.threadDump should print information about locks and deadlocks

Improved implementation of ActiveMQTestBase.threadDump which uses ThreadMXBean
for getting information about threads including locks and deadlocks.


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/fb76d9ae
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/fb76d9ae
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/fb76d9ae

Branch: refs/heads/master
Commit: fb76d9aeb09d698cc88cb7adaed922013ee7db3e
Parents: 60ce40f
Author: Erich Duda <du...@gmail.com>
Authored: Mon Oct 30 09:41:23 2017 +0100
Committer: Erich Duda <du...@gmail.com>
Committed: Tue Oct 31 08:04:11 2017 +0100

----------------------------------------------------------------------
 .../activemq/artemis/utils/ThreadDumpUtil.java  | 139 +++++++++++++++++++
 .../core/server/impl/ActiveMQServerImpl.java    |  24 +---
 .../artemis/tests/util/ActiveMQTestBase.java    |  30 +---
 3 files changed, 143 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fb76d9ae/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ThreadDumpUtil.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ThreadDumpUtil.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ThreadDumpUtil.java
new file mode 100644
index 0000000..2d94261
--- /dev/null
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ThreadDumpUtil.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.activemq.artemis.utils;
+
+import org.apache.activemq.artemis.logs.ActiveMQUtilLogger;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.management.LockInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+public final class ThreadDumpUtil {
+
+   public static String threadDump(final String msg) {
+
+      try (
+         StringWriter str = new StringWriter();
+         PrintWriter out = new PrintWriter(str)
+      ) {
+
+         ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+
+         out.println("*******************************************************************************");
+         out.println("Complete Thread dump " + msg);
+
+         for (ThreadInfo threadInfo : threadMXBean.dumpAllThreads(true, true)) {
+            out.println(threadInfoToString(threadInfo));
+         }
+
+         long[] deadlockedThreads = threadMXBean.findDeadlockedThreads();
+
+         if (deadlockedThreads != null && deadlockedThreads.length > 0) {
+            out.println("Deadlock detected!");
+            out.println();
+
+            for (ThreadInfo threadInfo : threadMXBean.getThreadInfo(deadlockedThreads, true, true)) {
+               out.println(threadInfoToString(threadInfo));
+            }
+         }
+
+         out.println("===============================================================================");
+         out.println("End Thread dump " + msg);
+         out.println("*******************************************************************************");
+
+         return str.toString();
+
+      } catch (IOException e) {
+         ActiveMQUtilLogger.LOGGER.error("Exception thrown during generating of thread dump.", e);
+      }
+
+      return "Generating of thread dump failed " + msg;
+
+   }
+
+   private static String threadInfoToString(ThreadInfo threadInfo) {
+      StringBuilder sb = new StringBuilder("\"" + threadInfo.getThreadName() + "\"" +
+            " Id=" + threadInfo.getThreadId() + " " +
+            threadInfo.getThreadState());
+      if (threadInfo.getLockName() != null) {
+         sb.append(" on " + threadInfo.getLockName());
+      }
+      if (threadInfo.getLockOwnerName() != null) {
+         sb.append(" owned by \"" + threadInfo.getLockOwnerName() +
+               "\" Id=" + threadInfo.getLockOwnerId());
+      }
+      if (threadInfo.isSuspended()) {
+         sb.append(" (suspended)");
+      }
+      if (threadInfo.isInNative()) {
+         sb.append(" (in native)");
+      }
+      sb.append('\n');
+      int i = 0;
+      for (; i < threadInfo.getStackTrace().length; i++) {
+         StackTraceElement ste = threadInfo.getStackTrace()[i];
+         sb.append("\tat " + ste.toString());
+         sb.append('\n');
+         if (i == 0 && threadInfo.getLockInfo() != null) {
+            Thread.State ts = threadInfo.getThreadState();
+            switch (ts) {
+               case BLOCKED:
+                  sb.append("\t-  blocked on " + threadInfo.getLockInfo());
+                  sb.append('\n');
+                  break;
+               case WAITING:
+                  sb.append("\t-  waiting on " + threadInfo.getLockInfo());
+                  sb.append('\n');
+                  break;
+               case TIMED_WAITING:
+                  sb.append("\t-  waiting on " + threadInfo.getLockInfo());
+                  sb.append('\n');
+                  break;
+               default:
+            }
+         }
+
+         for (MonitorInfo mi : threadInfo.getLockedMonitors()) {
+            if (mi.getLockedStackDepth() == i) {
+               sb.append("\t-  locked " + mi);
+               sb.append('\n');
+            }
+         }
+      }
+
+      LockInfo[] locks = threadInfo.getLockedSynchronizers();
+      if (locks.length > 0) {
+         sb.append("\n\tNumber of locked synchronizers = " + locks.length);
+         sb.append('\n');
+         for (LockInfo li : locks) {
+            sb.append("\t- " + li);
+            sb.append('\n');
+         }
+      }
+      sb.append('\n');
+      return sb.toString();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fb76d9ae/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index fff7a57..03c8010 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -169,6 +169,7 @@ import org.apache.activemq.artemis.utils.CompositeAddress;
 import org.apache.activemq.artemis.utils.ExecutorFactory;
 import org.apache.activemq.artemis.utils.ReusableLatch;
 import org.apache.activemq.artemis.utils.SecurityFormatter;
+import org.apache.activemq.artemis.utils.ThreadDumpUtil;
 import org.apache.activemq.artemis.utils.TimeUtils;
 import org.apache.activemq.artemis.utils.VersionLoader;
 import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
@@ -925,28 +926,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
 
    @Override
    public void threadDump() {
-      StringWriter str = new StringWriter();
-      PrintWriter out = new PrintWriter(str);
-
-      Map<Thread, StackTraceElement[]> stackTrace = Thread.getAllStackTraces();
-
-      out.println(ActiveMQMessageBundle.BUNDLE.generatingThreadDump());
-      out.println("*******************************************************************************");
-
-      for (Map.Entry<Thread, StackTraceElement[]> el : stackTrace.entrySet()) {
-         out.println("===============================================================================");
-         out.println(ActiveMQMessageBundle.BUNDLE.threadDump(el.getKey(), el.getKey().getName(), el.getKey().getId(), el.getKey().getThreadGroup()));
-         out.println();
-         for (StackTraceElement traceEl : el.getValue()) {
-            out.println(traceEl);
-         }
-      }
-
-      out.println("===============================================================================");
-      out.println(ActiveMQMessageBundle.BUNDLE.endThreadDump());
-      out.println("*******************************************************************************");
-
-      ActiveMQServerLogger.LOGGER.threadDump(str.toString());
+      ActiveMQServerLogger.LOGGER.threadDump(ThreadDumpUtil.threadDump(""));
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fb76d9ae/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index ba9d805..a63eec7 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -34,8 +34,6 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.lang.management.ManagementFactory;
 import java.lang.ref.WeakReference;
 import java.net.ServerSocket;
@@ -138,6 +136,7 @@ import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
 import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
 import org.apache.activemq.artemis.utils.Env;
 import org.apache.activemq.artemis.utils.FileUtil;
+import org.apache.activemq.artemis.utils.ThreadDumpUtil;
 import org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory;
 import org.apache.activemq.artemis.utils.RandomUtil;
 import org.apache.activemq.artemis.utils.ThreadLeakCheckRule;
@@ -619,34 +618,9 @@ public abstract class ActiveMQTestBase extends Assert {
    }
 
    public static String threadDump(final String msg) {
-      StringWriter str = new StringWriter();
-      PrintWriter out = new PrintWriter(str);
 
-      Map<Thread, StackTraceElement[]> stackTrace = Thread.getAllStackTraces();
+      return ThreadDumpUtil.threadDump(msg);
 
-      out.println("*******************************************************************************");
-      out.println("Complete Thread dump " + msg);
-
-      for (Map.Entry<Thread, StackTraceElement[]> el : stackTrace.entrySet()) {
-         out.println("===============================================================================");
-         out.println("Thread " + el.getKey() +
-                        " name = " +
-                        el.getKey().getName() +
-                        " id = " +
-                        el.getKey().getId() +
-                        " group = " +
-                        el.getKey().getThreadGroup());
-         out.println();
-         for (StackTraceElement traceEl : el.getValue()) {
-            out.println(traceEl);
-         }
-      }
-
-      out.println("===============================================================================");
-      out.println("End Thread dump " + msg);
-      out.println("*******************************************************************************");
-
-      return str.toString();
    }
 
    /**


[2/2] activemq-artemis git commit: This closes #1622

Posted by cl...@apache.org.
This closes #1622


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/3bdeed80
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/3bdeed80
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/3bdeed80

Branch: refs/heads/master
Commit: 3bdeed80c31e618141d468b0adbc1b6ac5e5bfbe
Parents: 60ce40f fb76d9a
Author: Clebert Suconic <cl...@apache.org>
Authored: Tue Oct 31 09:17:08 2017 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Tue Oct 31 09:17:08 2017 -0400

----------------------------------------------------------------------
 .../activemq/artemis/utils/ThreadDumpUtil.java  | 139 +++++++++++++++++++
 .../core/server/impl/ActiveMQServerImpl.java    |  24 +---
 .../artemis/tests/util/ActiveMQTestBase.java    |  30 +---
 3 files changed, 143 insertions(+), 50 deletions(-)
----------------------------------------------------------------------