[ASTERIXDB-2353][HYR][RT][FAIL] Provide complete thread dumps

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Implements a thread dump mechanism that does not truncate stack
  frames after the top 8

Change-Id: Id778615b3ac8951113d6b9ea027ad8650b784cb2
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2564
Sonar-Qube: Jenkins <jenk...@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhub...@apache.org>
Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu>


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

Branch: refs/heads/release-0.9.4-pre-rc
Commit: aa05501d4cd23eae0210e9da7e4b22721290debc
Parents: 5ff35c9
Author: Michael Blow <mb...@apache.org>
Authored: Tue Apr 3 18:49:03 2018 -0400
Committer: Michael Blow <mb...@apache.org>
Committed: Tue Apr 3 16:55:24 2018 -0700

----------------------------------------------------------------------
 .../org/apache/hyracks/util/ThreadDumpUtil.java | 64 +++++++++++++++++++-
 1 file changed, 61 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aa05501d/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/ThreadDumpUtil.java
----------------------------------------------------------------------
diff --git 
a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/ThreadDumpUtil.java
 
b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/ThreadDumpUtil.java
index 221d4b0..2de6700 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/ThreadDumpUtil.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/ThreadDumpUtil.java
@@ -19,7 +19,9 @@
 package org.apache.hyracks.util;
 
 import java.io.IOException;
+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;
 import java.util.ArrayList;
@@ -29,6 +31,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Stream;
 
+import org.apache.commons.lang3.mutable.MutableInt;
+
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -100,8 +104,62 @@ public class ThreadDumpUtil {
     }
 
     public static String takeDumpString() {
-        StringBuilder buf = new StringBuilder(2048);
-        Stream.of(threadMXBean.dumpAllThreads(true, 
true)).forEach(buf::append);
-        return buf.toString();
+        ThreadDumpHelper helper = new ThreadDumpHelper();
+        Stream.of(threadMXBean.dumpAllThreads(true, 
true)).forEach(helper::addThread);
+        return helper.dumpAsString();
+    }
+
+    static class ThreadDumpHelper {
+
+        private final StringBuilder buf = new StringBuilder(32 * 1024);
+
+        private ThreadDumpHelper() {
+        }
+
+        private void addThread(ThreadInfo ti) {
+            buf.append('\n');
+            quote(ti.getThreadName()).append(" 
[tid=").append(ti.getThreadId()).append(" state=")
+                    .append(ti.getThreadState());
+
+            if (ti.getLockName() != null) {
+                buf.append(" lock=").append(ti.getLockName());
+                if (ti.getLockOwnerName() != null) {
+                    buf.append(" lockOwner=");
+                    quote(ti.getLockOwnerName()).append(" 
(tid=").append(ti.getLockOwnerId());
+                }
+            }
+            if (ti.isSuspended()) {
+                buf.append(" suspended=true");
+            }
+            buf.append("]\n");
+            MutableInt depth = new MutableInt();
+            for (StackTraceElement frame : ti.getStackTrace()) {
+                int thisDepth = depth.getAndIncrement();
+                buf.append("\tat ").append(frame).append('\n');
+                Stream.of(ti.getLockedMonitors()).filter(m -> 
m.getLockedStackDepth() == thisDepth)
+                        .forEach(this::output);
+            }
+            LockInfo[] lockedSynchronizers = ti.getLockedSynchronizers();
+            if (lockedSynchronizers.length > 0) {
+                buf.append("\n\tLocked synchronizers:\n");
+                Stream.of(lockedSynchronizers).forEachOrdered(this::output);
+            }
+        }
+
+        private StringBuilder quote(Object quotable) {
+            return buf.append('"').append(quotable).append('"');
+        }
+
+        private StringBuilder output(MonitorInfo info) {
+            return buf.append("\t- <").append("locked 
").append(info).append(">\n");
+        }
+
+        private StringBuilder output(LockInfo info) {
+            return buf.append("\t- ").append("").append(info).append("\n");
+        }
+
+        public String dumpAsString() {
+            return buf.toString();
+        }
     }
 }

Reply via email to