From 07699485695d8c0e28bbca535a70ba0cfea7c69c Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Tue, 2 Oct 2018 18:52:53 +0300 Subject: [PATCH] IDEA-199822 Create extension point to provide captured stack frames by e.g. evaluation expression in debugged jvm --- .../engine/AsyncStackTraceProvider.java | 20 ++++++++++++++++++ .../debugger/engine/AsyncStacksUtils.java | 13 ++++++++++++ .../debugger/engine/JavaExecutionStack.java | 21 +++++++++---------- .../StackCapturingLineBreakpoint.java | 18 ++++++++++++++++ resources/src/META-INF/JavaIdePlugin.xml | 5 +++++ 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/engine/AsyncStackTraceProvider.java diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStackTraceProvider.java b/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStackTraceProvider.java new file mode 100644 index 000000000000..bdb986304807 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStackTraceProvider.java @@ -0,0 +1,20 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.debugger.engine; + +import com.intellij.debugger.memory.utils.StackFrameItem; +import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author egor + */ +public interface AsyncStackTraceProvider { + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.debugger.asyncStackTraceProvider"); + + @Nullable + List getAsyncStackTrace(JavaStackFrame stackFrame, SuspendContextImpl suspendContext); + + boolean isKeepCurrentFrame(); +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStacksUtils.java b/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStacksUtils.java index c5631b53207b..6fb433091a67 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStacksUtils.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/AsyncStacksUtils.java @@ -278,4 +278,17 @@ public class AsyncStacksUtils { public static int getMaxStackLength() { return Registry.intValue("debugger.async.stacks.max.depth", 500); } + + public static class AgentAsyncStackTraceProvider implements AsyncStackTraceProvider { + @Nullable + @Override + public List getAsyncStackTrace(JavaStackFrame stackFrame, SuspendContextImpl suspendContext) { + return getAgentRelatedStack(stackFrame, suspendContext); + } + + @Override + public boolean isKeepCurrentFrame() { + return true; + } + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java index 8b11ca752c0e..d1070e919549 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java @@ -2,7 +2,6 @@ package com.intellij.debugger.engine; import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.actions.AsyncStacksToggleAction; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; @@ -11,7 +10,6 @@ import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.memory.utils.StackFrameItem; import com.intellij.debugger.ui.breakpoints.BreakpointIntentionAction; -import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint; import com.intellij.debugger.ui.impl.watch.MethodsTracker; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; import com.intellij.icons.AllIcons; @@ -20,7 +18,6 @@ import com.intellij.ui.ColoredTextContainer; import com.intellij.ui.SimpleTextAttributes; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XStackFrame; -import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import com.sun.jdi.Location; import com.sun.jdi.Method; @@ -218,15 +215,17 @@ public class JavaExecutionStack extends XExecutionStack { } List relatedStack = null; - if (frame instanceof JavaStackFrame && - AsyncStacksToggleAction.isAsyncStacksEnabled((XDebugSessionImpl)myDebugProcess.getXdebugProcess().getSession())) { - relatedStack = StackCapturingLineBreakpoint.getRelatedStack(frameProxy, suspendContext); - if (relatedStack != null) { - appendRelatedStack(relatedStack); - return; + if (frame instanceof JavaStackFrame) { + for (AsyncStackTraceProvider asyncStackTraceProvider : AsyncStackTraceProvider.EP_NAME.getExtensionList()) { + relatedStack = asyncStackTraceProvider.getAsyncStackTrace(((JavaStackFrame)frame), suspendContext); + if (relatedStack != null) { + if (asyncStackTraceProvider.isKeepCurrentFrame()) { + break; + } + appendRelatedStack(relatedStack); + return; + } } - // append agent stack after the next frame - relatedStack = AsyncStacksUtils.getAgentRelatedStack((JavaStackFrame)frame, suspendContext); } myDebugProcess.getManagerThread().schedule( diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java index 8b34e223541e..234a6c572248 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java @@ -3,6 +3,7 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.actions.AsyncStacksToggleAction; import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.engine.evaluation.expression.Evaluator; @@ -27,6 +28,7 @@ import com.intellij.psi.PsiElement; import com.intellij.ui.SimpleColoredComponent; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FixedHashMap; +import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; import one.util.streamex.StreamEx; @@ -293,4 +295,20 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { myEvaluatorCache.clear(); } } + + public static class CaptureAsyncStackTraceProvider implements AsyncStackTraceProvider { + @Nullable + @Override + public List getAsyncStackTrace(JavaStackFrame stackFrame, SuspendContextImpl suspendContext) { + if (AsyncStacksToggleAction.isAsyncStacksEnabled((XDebugSessionImpl)suspendContext.getDebugProcess().getXdebugProcess().getSession())) { + return getRelatedStack(stackFrame.getStackFrameProxy(), suspendContext); + } + return null; + } + + @Override + public boolean isKeepCurrentFrame() { + return false; + } + } } diff --git a/resources/src/META-INF/JavaIdePlugin.xml b/resources/src/META-INF/JavaIdePlugin.xml index 46e29c45083c..7ed6c575ddbe 100644 --- a/resources/src/META-INF/JavaIdePlugin.xml +++ b/resources/src/META-INF/JavaIdePlugin.xml @@ -113,6 +113,9 @@ + + @@ -299,6 +302,8 @@ + +