IDEA-199822 Create extension point to provide captured stack frames by e.g. evaluation expression in debugged jvm

This commit is contained in:
Egor Ushakov
2018-10-02 18:53:40 +03:00
parent cd81359518
commit 0769948569
5 changed files with 66 additions and 11 deletions
@@ -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<AsyncStackTraceProvider> EP_NAME = ExtensionPointName.create("com.intellij.debugger.asyncStackTraceProvider");
@Nullable
List<StackFrameItem> getAsyncStackTrace(JavaStackFrame stackFrame, SuspendContextImpl suspendContext);
boolean isKeepCurrentFrame();
}
@@ -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<StackFrameItem> getAsyncStackTrace(JavaStackFrame stackFrame, SuspendContextImpl suspendContext) {
return getAgentRelatedStack(stackFrame, suspendContext);
}
@Override
public boolean isKeepCurrentFrame() {
return true;
}
}
}
@@ -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<StackFrameItem> 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(
@@ -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<StackFrameItem> 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;
}
}
}
+5
View File
@@ -113,6 +113,9 @@
<extensionPoint name="debugger.frameExtraVarsProvider"
interface="com.intellij.debugger.engine.FrameExtraVariablesProvider"/>
<extensionPoint name="debugger.asyncStackTraceProvider"
interface="com.intellij.debugger.engine.AsyncStackTraceProvider"/>
<extensionPoint name="debugger.sourcePositionProvider"
interface="com.intellij.debugger.engine.SourcePositionProvider"/>
@@ -299,6 +302,8 @@
<debugger.sourcePositionHighlighter implementation="com.intellij.debugger.engine.JavaSourcePositionHighlighter"/>
<java.elementFinder implementation="com.intellij.debugger.impl.AlternativeJreClassFinder" order="last"/>
<additionalLibraryRootsProvider implementation="com.intellij.execution.AlternativeSdkRootsProvider"/>
<debugger.asyncStackTraceProvider implementation="com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint$CaptureAsyncStackTraceProvider"/>
<debugger.asyncStackTraceProvider implementation="com.intellij.debugger.engine.AsyncStacksUtils$AgentAsyncStackTraceProvider"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$BooleanRenderer"/>
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.UnboxableTypeRenderer$ByteRenderer"/>