From a5d1b95ec47b77abba47dcc772cd33812d8b3fc3 Mon Sep 17 00:00:00 2001 From: jkhajuria Date: Thu, 12 Jun 2025 18:52:31 -0700 Subject: [PATCH 1/4] add thread dump row class --- .../eclipse/jifa/tda/model/ThreadDumpRow.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/model/ThreadDumpRow.java diff --git a/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/model/ThreadDumpRow.java b/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/model/ThreadDumpRow.java new file mode 100644 index 00000000..7f04e6d7 --- /dev/null +++ b/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/model/ThreadDumpRow.java @@ -0,0 +1,39 @@ +package org.eclipse.jifa.tda.model; + +import org.eclipse.jifa.tda.enums.OSTreadState; + +import lombok.Data; + +@Data +public class ThreadDumpRow { + + private String name; + + private int tid; + + private OSTreadState state; + + private int stackDepth; + + private Frame[] frames; + + private double elapsedTime; + + private double cpuTime; + + private int lineNumberStart; + + private int lineNumberEnd; + + public ThreadDumpRow(String name, int id, OSTreadState osThreadState, int length, Frame[] frames, double elapsed, double cpu, int lineStart, int lineEnd) { + this.name = name; + this.tid = id; + this.state = osThreadState; + this.stackDepth = length; + this.frames = frames; + this.elapsedTime = elapsed; + this.cpuTime = cpu; + this.lineNumberStart = lineStart; + this.lineNumberEnd = lineEnd; + } +} From 5f2bd430de1a79a845084b8d6fc15b2d90a3de3b Mon Sep 17 00:00:00 2001 From: jkhajuria Date: Thu, 12 Jun 2025 18:52:46 -0700 Subject: [PATCH 2/4] add new endpoint for getting thread dump rows --- .../eclipse/jifa/tda/ThreadDumpAnalyzer.java | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/ThreadDumpAnalyzer.java b/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/ThreadDumpAnalyzer.java index 22529a94..149335bc 100644 --- a/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/ThreadDumpAnalyzer.java +++ b/analysis/thread-dump/src/main/java/org/eclipse/jifa/tda/ThreadDumpAnalyzer.java @@ -22,14 +22,9 @@ import org.eclipse.jifa.common.domain.vo.PageView; import org.eclipse.jifa.common.util.PageViewBuilder; import org.eclipse.jifa.tda.enums.MonitorState; +import org.eclipse.jifa.tda.enums.OSTreadState; import org.eclipse.jifa.tda.enums.ThreadType; -import org.eclipse.jifa.tda.model.CallSiteTree; -import org.eclipse.jifa.tda.model.Frame; -import org.eclipse.jifa.tda.model.IdentityPool; -import org.eclipse.jifa.tda.model.JavaThread; -import org.eclipse.jifa.tda.model.Monitor; -import org.eclipse.jifa.tda.model.RawMonitor; -import org.eclipse.jifa.tda.model.Snapshot; +import org.eclipse.jifa.tda.model.*; import org.eclipse.jifa.tda.model.Thread; import org.eclipse.jifa.tda.parser.ParserFactory; import org.eclipse.jifa.tda.util.CollectionUtil; @@ -43,11 +38,8 @@ import java.io.IOException; import java.io.LineNumberReader; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * Thread dump analyzer @@ -305,4 +297,31 @@ public Map threadCountsByMonitor(int id) { map.forEach((s, l) -> counts.put(s, l.size())); return counts; } + + /** + * @return rows of a thread dump table + */ + public List rows(PagingRequest paging) { + + List threadDumpRows = new ArrayList<>(snapshot.getJavaThreads().stream().map(t -> { + + Frame[] frames = null; + int length = 0; + + if (t.getTrace() != null) { + frames = t.getTrace().getFrames(); + length = frames.length; + } + + return new ThreadDumpRow(t.getName(), t.getId(), t.getOsThreadState(), length, frames, t.getElapsed(), t.getCpu(), t.getLineStart(), t.getLineEnd()); + }).toList()); + + List nonJavaThreadDumpRows = snapshot.getNonJavaThreads().stream().map(t -> { + return new ThreadDumpRow(t.getName(), t.getId(), t.getOsThreadState(), 0, new Frame[]{}, t.getElapsed(), t.getCpu(), t.getLineStart(), t.getLineEnd()); + }).toList(); + + threadDumpRows.addAll(nonJavaThreadDumpRows); + + return threadDumpRows; + } } From 7127d6a22bd6aa1de2eb1b9c01869f53234265ab Mon Sep 17 00:00:00 2001 From: jkhajuria Date: Thu, 12 Jun 2025 18:52:57 -0700 Subject: [PATCH 3/4] new thread dump grid view --- .../src/components/threaddump/ThreadDump.vue | 62 +++++++++++++++++- .../threaddump/ThreadViewerGrid.vue | 63 +++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/threaddump/ThreadViewerGrid.vue diff --git a/frontend/src/components/threaddump/ThreadDump.vue b/frontend/src/components/threaddump/ThreadDump.vue index 7ec002ba..889dd7c8 100644 --- a/frontend/src/components/threaddump/ThreadDump.vue +++ b/frontend/src/components/threaddump/ThreadDump.vue @@ -28,6 +28,7 @@ import Content from '@/components/threaddump/Content.vue'; import Thread from '@/components/threaddump/Thread.vue'; import Monitor from '@/components/threaddump/Monitor.vue'; import CallSiteTree from '@/components/threaddump/CallSiteTree.vue'; +import ThreadViewerGrid from '@/components/threaddump/ThreadViewerGrid.vue'; const { request } = useAnalysisApiRequester(); @@ -36,7 +37,9 @@ const activeNames = ref([ 'threadSummary', 'threadGroupSummary', 'javaMonitors', - 'callSiteTree' + 'callSiteTree', + 'Table View', + 'fileContent' ]); const deadLockCount = ref(0); @@ -66,6 +69,10 @@ const threadDialogVisible = ref(false); const selectedThreadType = ref(); const selectedThreadGroup = ref(); +const threadsArray = ref([]); +const selectedThread = ref(null); +const selectedThreadContent = ref(''); + function sum(arr) { return arr.reduce((l, r) => l + r); } @@ -92,6 +99,24 @@ function showThreadsOfGroup(group) { threadDialogVisible.value = true; } +function onThreadSelected(thread) { + selectedThread.value = thread; + const lineNumberStart = thread.lineNumberStart; + const lineNumberEnd = thread.lineNumberEnd; + console.log("Hello"); + + console.log(thread) + + if (lineNumberStart && lineNumberEnd) { + // Calculate limit as end - start + 1 + const limit = lineNumberEnd - lineNumberStart + 1; + request('content', { lineNo: lineNumberStart, lineLimit: limit }).then((data) => { + // data.content is assumed to be a list of strings + selectedThreadContent.value = data.content.join('\n'); + }); + } +} + onMounted(() => { loading.value = true; request('overview').then((overview) => { @@ -178,6 +203,21 @@ onMounted(() => { threadGroupStats.value = _threadGroupStats; loading.value = false; }); + + request('rows').then((threadsData) => { + console.log(threadsData); + threadsArray.value = threadsData.map((t) => ({ + tid: t.tid, + name: t.name, + state: t.state, + stackDepth: t.stackDepth, + frames: t.frames, + cpuTime: t.cpuTime, + elapsedTime: t.elapsedTime, + lineNumberStart: t.lineNumberStart, + lineNumberEnd: t.lineNumberEnd + })); + }); });