mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
[debugger] IDEA-338723 Fix suspending behavior while stepping in coroutines
Race conditions in continuation filtering in suspend-all mode force to switch to suspend-thread mode. But that behavior is different from suspend-all mode during regular stepping. To solve this problem, the workaround is implemented: found suspended thread calls suspend-all request (actually, track some method entering any thread). That next suspension resumes the original one-thead suspension and replaces the suspension to itself. So a user will just see "regular" suspend-all thread picture. Note 1: Technically, the replaced suspended thread has another "primary" thread. It may lead to some problems. Note 2: Suspend one-thread mode is working supported in coroutine stepping. But now it does not trigger thread switching (just notification is showing). GitOrigin-RevId: 90d823e0ece4b6ce3a548ad984cd6e824dc516b4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d4f36c6437
commit
8b38a4f0d4
@@ -636,12 +636,17 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
// Don't try to check breakpoint's condition or evaluate its log expression,
|
// Don't try to check breakpoint's condition or evaluate its log expression,
|
||||||
// because these evaluations may lead to skipping of more important stepping events,
|
// because these evaluations may lead to skipping of more important stepping events,
|
||||||
// see IDEA-336282.
|
// see IDEA-336282.
|
||||||
if (!DebuggerSession.filterBreakpointsDuringSteppingUsingDebuggerEngine()) {
|
boolean filterWasUsed = false;
|
||||||
|
boolean shouldIgnoreThreadFiltering = requestor == null || !requestor.shouldIgnoreThreadFiltering();
|
||||||
|
if (!DebuggerSession.filterBreakpointsDuringSteppingUsingDebuggerEngine() && shouldIgnoreThreadFiltering) {
|
||||||
LightOrRealThreadInfo filter = getRequestsManager().getFilterThread();
|
LightOrRealThreadInfo filter = getRequestsManager().getFilterThread();
|
||||||
if (filter != null && !filter.checkSameThread(thread, suspendContext)) {
|
if (filter != null) {
|
||||||
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
if (!filter.checkSameThread(thread, suspendContext)) {
|
||||||
suspendManager.voteResume(suspendContext);
|
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
||||||
return;
|
suspendManager.voteResume(suspendContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
filterWasUsed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,8 +736,18 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
// // As resume() implicitly cleares the filter, the filter must be always applied _before_ any resume() action happens
|
// // As resume() implicitly cleares the filter, the filter must be always applied _before_ any resume() action happens
|
||||||
// myBreakpointManager.applyThreadFilter(DebugProcessEvents.this, event.thread());
|
// myBreakpointManager.applyThreadFilter(DebugProcessEvents.this, event.thread());
|
||||||
//}
|
//}
|
||||||
suspendManager.voteSuspend(suspendContext);
|
if (filterWasUsed && suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD &&
|
||||||
showStatusText(DebugProcessEvents.this, event);
|
requestor.needReplaceWithAllThreadSuspendContext()) {
|
||||||
|
// Do not vote to resume.
|
||||||
|
// Instead, create an auxiliary request to correctly stop all threads as soon as possible.
|
||||||
|
// [SuspendOtherThreadsRequestor] will resume this suspendContext when the request hits.
|
||||||
|
// Resume will be without voting.
|
||||||
|
SuspendOtherThreadsRequestor.enableRequest(mySession.getProcess(), suspendContext);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
suspendManager.voteSuspend(suspendContext);
|
||||||
|
showStatusText(DebugProcessEvents.this, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1853,8 +1853,9 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
|||||||
public RunToCursorCommand(SuspendContextImpl suspendContext, @NotNull XSourcePosition position, final boolean ignoreBreakpoints) {
|
public RunToCursorCommand(SuspendContextImpl suspendContext, @NotNull XSourcePosition position, final boolean ignoreBreakpoints) {
|
||||||
super(suspendContext, null);
|
super(suspendContext, null);
|
||||||
myIgnoreBreakpoints = ignoreBreakpoints;
|
myIgnoreBreakpoints = ignoreBreakpoints;
|
||||||
myRunToCursorBreakpoint =
|
boolean needReplaceWithAllThreadSuspendContext = suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL;
|
||||||
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addRunToCursorBreakpoint(position, ignoreBreakpoints);
|
myRunToCursorBreakpoint = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager()
|
||||||
|
.addRunToCursorBreakpoint(position, ignoreBreakpoints, needReplaceWithAllThreadSuspendContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1985,7 +1986,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void applyThreadFilter(@Nullable LightOrRealThreadInfo threadInfo) {
|
protected void applyThreadFilter(@Nullable LightOrRealThreadInfo threadInfo) {
|
||||||
if (getSuspendContext().getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
|
boolean isLightThread = threadInfo != null && threadInfo.getRealThread() == null;
|
||||||
|
if (isLightThread || getSuspendContext().getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
|
||||||
// there could be explicit resume as a result of call to voteSuspend()
|
// there could be explicit resume as a result of call to voteSuspend()
|
||||||
// e.g. when breakpoint was considered invalid, in that case the filter will be applied _after_
|
// e.g. when breakpoint was considered invalid, in that case the filter will be applied _after_
|
||||||
// resuming and all breakpoints in other threads will be ignored.
|
// resuming and all breakpoints in other threads will be ignored.
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
|
|||||||
|
|
||||||
private JavaExecutionStack myActiveExecutionStack;
|
private JavaExecutionStack myActiveExecutionStack;
|
||||||
|
|
||||||
|
private @Nullable ThreadReferenceProxyImpl myAnotherThreadToFocus = null;
|
||||||
|
|
||||||
SuspendContextImpl(@NotNull DebugProcessImpl debugProcess,
|
SuspendContextImpl(@NotNull DebugProcessImpl debugProcess,
|
||||||
@MagicConstant(flagsFromClass = EventRequest.class) int suspendPolicy,
|
@MagicConstant(flagsFromClass = EventRequest.class) int suspendPolicy,
|
||||||
int eventVotes,
|
int eventVotes,
|
||||||
@@ -334,4 +336,12 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
|
|||||||
|
|
||||||
private static final Comparator<JavaExecutionStack> THREADS_SUSPEND_AND_NAME_COMPARATOR =
|
private static final Comparator<JavaExecutionStack> THREADS_SUSPEND_AND_NAME_COMPARATOR =
|
||||||
Comparator.comparing(JavaExecutionStack::getThreadProxy, SUSPEND_FIRST_COMPARATOR).thenComparing(THREAD_NAME_COMPARATOR);
|
Comparator.comparing(JavaExecutionStack::getThreadProxy, SUSPEND_FIRST_COMPARATOR).thenComparing(THREAD_NAME_COMPARATOR);
|
||||||
|
|
||||||
|
public @Nullable ThreadReferenceProxyImpl getAnotherThreadToFocus() {
|
||||||
|
return myAnotherThreadToFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnotherThreadToFocus(@Nullable ThreadReferenceProxyImpl threadToFocus) {
|
||||||
|
myAnotherThreadToFocus = threadToFocus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
|
package com.intellij.debugger.engine;
|
||||||
|
|
||||||
|
import com.intellij.debugger.InstanceFilter;
|
||||||
|
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||||
|
import com.intellij.debugger.settings.DebuggerSettings;
|
||||||
|
import com.intellij.debugger.ui.breakpoints.FilteredRequestor;
|
||||||
|
import com.intellij.ui.classFilter.ClassFilter;
|
||||||
|
import com.sun.jdi.event.LocatableEvent;
|
||||||
|
import com.sun.jdi.request.EventRequest;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class SuspendOtherThreadsRequestor implements FilteredRequestor {
|
||||||
|
|
||||||
|
private static final ClassFilter[] CLASS_EXCLUSION_FILTERS = {
|
||||||
|
new ClassFilter("java.*"),
|
||||||
|
new ClassFilter("jdk.*"),
|
||||||
|
new ClassFilter("sun.*"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private final @NotNull DebugProcessImpl myProcess;
|
||||||
|
private final @NotNull SuspendContextImpl myThreadSuspendContext;
|
||||||
|
|
||||||
|
SuspendOtherThreadsRequestor(@NotNull DebugProcessImpl process, @NotNull SuspendContextImpl threadSuspendContext) {
|
||||||
|
myProcess = process;
|
||||||
|
myThreadSuspendContext = threadSuspendContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void enableRequest(DebugProcessImpl process, @NotNull SuspendContextImpl threadSuspendContext) {
|
||||||
|
var requestor = new SuspendOtherThreadsRequestor(process, threadSuspendContext);
|
||||||
|
var request = process.getRequestsManager().createMethodEntryRequest(requestor);
|
||||||
|
|
||||||
|
request.setSuspendPolicy(EventRequest.SUSPEND_ALL);
|
||||||
|
request.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processLocatableEvent(@NotNull SuspendContextCommandImpl action, LocatableEvent event) {
|
||||||
|
myProcess.getRequestsManager().deleteRequest(this);
|
||||||
|
|
||||||
|
SuspendContextImpl suspendContext = action.getSuspendContext();
|
||||||
|
if (suspendContext == null) return false;
|
||||||
|
|
||||||
|
// Need to 'replace' the myThreadSuspendContext (single-thread suspend context passed filtering) with this one.
|
||||||
|
suspendContext.setAnotherThreadToFocus(myThreadSuspendContext.getThread());
|
||||||
|
|
||||||
|
// Note, myThreadSuspendContext is resuming without SuspendManager#voteSuspend.
|
||||||
|
// Look at the end of DebugProcessEvents#processLocatableEvent for more details.
|
||||||
|
myProcess.getSuspendManager().voteResume(myThreadSuspendContext);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSuspendPolicy() {
|
||||||
|
return DebuggerSettings.SUSPEND_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInstanceFiltersEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InstanceFilter[] getInstanceFilters() {
|
||||||
|
return InstanceFilter.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCountFilterEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCountFilter() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClassFiltersEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassFilter[] getClassFilters() {
|
||||||
|
return ClassFilter.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassFilter[] getClassExclusionFilters() {
|
||||||
|
return CLASS_EXCLUSION_FILTERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldIgnoreThreadFiltering() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,14 @@ public interface LocatableEventRequestor extends Requestor {
|
|||||||
*/
|
*/
|
||||||
String getSuspendPolicy();
|
String getSuspendPolicy();
|
||||||
|
|
||||||
|
default boolean shouldIgnoreThreadFiltering() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean needReplaceWithAllThreadSuspendContext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
class EventProcessingException extends Exception {
|
class EventProcessingException extends Exception {
|
||||||
private final @NlsContexts.DialogTitle String myTitle;
|
private final @NlsContexts.DialogTitle String myTitle;
|
||||||
|
|
||||||
|
|||||||
@@ -368,11 +368,15 @@ public final class DebuggerSession implements AbstractDebuggerSession {
|
|||||||
public void resume() {
|
public void resume() {
|
||||||
final SuspendContextImpl suspendContext = getSuspendContext();
|
final SuspendContextImpl suspendContext = getSuspendContext();
|
||||||
if (suspendContext != null) {
|
if (suspendContext != null) {
|
||||||
clearSteppingThrough();
|
resumeSuspendContext(suspendContext);
|
||||||
resumeAction(myDebugProcess.createResumeCommand(suspendContext), Event.RESUME);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resumeSuspendContext(SuspendContextImpl suspendContext) {
|
||||||
|
clearSteppingThrough();
|
||||||
|
resumeAction(myDebugProcess.createResumeCommand(suspendContext), Event.RESUME);
|
||||||
|
}
|
||||||
|
|
||||||
public void resetIgnoreStepFiltersFlag() {
|
public void resetIgnoreStepFiltersFlag() {
|
||||||
myIgnoreFiltersFrameCountThreshold = 0;
|
myIgnoreFiltersFrameCountThreshold = 0;
|
||||||
}
|
}
|
||||||
@@ -484,7 +488,8 @@ public final class DebuggerSession implements AbstractDebuggerSession {
|
|||||||
public void paused(final SuspendContextImpl suspendContext) {
|
public void paused(final SuspendContextImpl suspendContext) {
|
||||||
LOG.debug("paused");
|
LOG.debug("paused");
|
||||||
|
|
||||||
ThreadReferenceProxyImpl currentThread = suspendContext.getThread();
|
ThreadReferenceProxyImpl anotherThreadToFocus = suspendContext.getAnotherThreadToFocus();
|
||||||
|
ThreadReferenceProxyImpl currentThread = anotherThreadToFocus != null ? anotherThreadToFocus : suspendContext.getThread();
|
||||||
|
|
||||||
if (!shouldSetAsActiveContext(suspendContext)) {
|
if (!shouldSetAsActiveContext(suspendContext)) {
|
||||||
notifyThreadsRefresh();
|
notifyThreadsRefresh();
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ public class BreakpointManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public RunToCursorBreakpoint addRunToCursorBreakpoint(@NotNull XSourcePosition position, final boolean ignoreBreakpoints) {
|
public RunToCursorBreakpoint addRunToCursorBreakpoint(@NotNull XSourcePosition position, boolean ignoreBreakpoints, boolean needReplaceWithAllThreadSuspendContext) {
|
||||||
return RunToCursorBreakpoint.create(myProject, position, ignoreBreakpoints);
|
return RunToCursorBreakpoint.create(myProject, position, ignoreBreakpoints, needReplaceWithAllThreadSuspendContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -22,11 +22,13 @@ public class RunToCursorBreakpoint extends SyntheticLineBreakpoint implements St
|
|||||||
private final boolean myRestoreBreakpoints;
|
private final boolean myRestoreBreakpoints;
|
||||||
@NotNull
|
@NotNull
|
||||||
protected final SourcePosition myCustomPosition;
|
protected final SourcePosition myCustomPosition;
|
||||||
|
private final boolean myNeedReplaceWithAllThreadSuspendContext;
|
||||||
|
|
||||||
protected RunToCursorBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, boolean restoreBreakpoints) {
|
protected RunToCursorBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, boolean restoreBreakpoints, boolean needReplaceWithAllThreadSuspendContext) {
|
||||||
super(project);
|
super(project);
|
||||||
myCustomPosition = pos;
|
myCustomPosition = pos;
|
||||||
myRestoreBreakpoints = restoreBreakpoints;
|
myRestoreBreakpoints = restoreBreakpoints;
|
||||||
|
myNeedReplaceWithAllThreadSuspendContext = needReplaceWithAllThreadSuspendContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -70,12 +72,15 @@ public class RunToCursorBreakpoint extends SyntheticLineBreakpoint implements St
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected static RunToCursorBreakpoint create(@NotNull Project project, @NotNull XSourcePosition position, boolean restoreBreakpoints) {
|
protected static RunToCursorBreakpoint create(@NotNull Project project,
|
||||||
|
@NotNull XSourcePosition position,
|
||||||
|
boolean restoreBreakpoints,
|
||||||
|
boolean needReplaceWithAllThreadSuspendContext) {
|
||||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(position.getFile());
|
PsiFile psiFile = PsiManager.getInstance(project).findFile(position.getFile());
|
||||||
if (psiFile == null) {
|
if (psiFile == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new RunToCursorBreakpoint(project, SourcePosition.createFromOffset(psiFile, position.getOffset()), restoreBreakpoints);
|
return new RunToCursorBreakpoint(project, SourcePosition.createFromOffset(psiFile, position.getOffset()), restoreBreakpoints, needReplaceWithAllThreadSuspendContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,4 +91,9 @@ public class RunToCursorBreakpoint extends SyntheticLineBreakpoint implements St
|
|||||||
public boolean track() {
|
public boolean track() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needReplaceWithAllThreadSuspendContext() {
|
||||||
|
return myNeedReplaceWithAllThreadSuspendContext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint {
|
|||||||
@Nullable private RequestHint myHint;
|
@Nullable private RequestHint myHint;
|
||||||
|
|
||||||
protected StepIntoBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, @NotNull BreakpointStepMethodFilter filter) {
|
protected StepIntoBreakpoint(@NotNull Project project, @NotNull SourcePosition pos, @NotNull BreakpointStepMethodFilter filter) {
|
||||||
super(project, pos, false);
|
super(project, pos, false, false);
|
||||||
myFilter = filter;
|
myFilter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import com.intellij.testFramework.EdtTestUtil;
|
|||||||
import com.intellij.testFramework.RunAll;
|
import com.intellij.testFramework.RunAll;
|
||||||
import com.intellij.testFramework.UsefulTestCase;
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
import com.intellij.util.ThrowableRunnable;
|
import com.intellij.util.ThrowableRunnable;
|
||||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
|
|
||||||
import com.intellij.util.ui.EDT;
|
import com.intellij.util.ui.EDT;
|
||||||
import com.intellij.util.ui.UIUtil;
|
import com.intellij.util.ui.UIUtil;
|
||||||
import com.intellij.xdebugger.*;
|
import com.intellij.xdebugger.*;
|
||||||
@@ -453,7 +452,20 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DebuggerContextImpl createDebuggerContext(final SuspendContextImpl suspendContext) {
|
public DebuggerContextImpl createDebuggerContext(final SuspendContextImpl suspendContext) {
|
||||||
return createDebuggerContext(suspendContext, suspendContext.getFrameProxy());
|
StackFrameProxyImpl proxy = getFrameProxy(suspendContext);
|
||||||
|
return createDebuggerContext(suspendContext, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static StackFrameProxyImpl getFrameProxy(@NotNull SuspendContextImpl suspendContext) {
|
||||||
|
if (suspendContext.getAnotherThreadToFocus() != null) {
|
||||||
|
try {
|
||||||
|
return suspendContext.getAnotherThreadToFocus().frame(0);
|
||||||
|
}
|
||||||
|
catch (EvaluateException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suspendContext.getFrameProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void printLocation(SuspendContextImpl suspendContext) {
|
protected void printLocation(SuspendContextImpl suspendContext) {
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ import org.jetbrains.eval4j.Value
|
|||||||
import org.jetbrains.eval4j.jdi.asValue
|
import org.jetbrains.eval4j.jdi.asValue
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
|
||||||
|
import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findStringWithPrefixes
|
||||||
import org.jetbrains.kotlin.idea.compilerPlugin.kotlinxSerialization.KotlinSerializationEnabledChecker
|
import org.jetbrains.kotlin.idea.compilerPlugin.kotlinxSerialization.KotlinSerializationEnabledChecker
|
||||||
import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner
|
import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DebugContextProvider
|
import org.jetbrains.kotlin.idea.debugger.evaluate.DebugContextProvider
|
||||||
@@ -40,8 +42,6 @@ import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinter
|
|||||||
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinterDelegate
|
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinterDelegate
|
||||||
import org.jetbrains.kotlin.idea.debugger.test.util.KotlinOutputChecker
|
import org.jetbrains.kotlin.idea.debugger.test.util.KotlinOutputChecker
|
||||||
import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstruction
|
import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstruction
|
||||||
import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
|
|
||||||
import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findStringWithPrefixes
|
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinBaseTest
|
import org.jetbrains.kotlin.idea.test.KotlinBaseTest
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -210,7 +210,7 @@ abstract class AbstractIrKotlinEvaluateExpressionTest : KotlinDescriptorTestCase
|
|||||||
val sourcePosition = ContextUtil.getSourcePosition(suspendContext)
|
val sourcePosition = ContextUtil.getSourcePosition(suspendContext)
|
||||||
|
|
||||||
// Default test debuggerContext doesn't provide a valid stackFrame so we have to create one more for evaluation purposes.
|
// Default test debuggerContext doesn't provide a valid stackFrame so we have to create one more for evaluation purposes.
|
||||||
val frameProxy = suspendContext.frameProxy
|
val frameProxy = getFrameProxy(suspendContext)
|
||||||
val threadProxy = frameProxy?.threadProxy()
|
val threadProxy = frameProxy?.threadProxy()
|
||||||
val debuggerContext = createDebuggerContext(myDebuggerSession, suspendContext, threadProxy, frameProxy)
|
val debuggerContext = createDebuggerContext(myDebuggerSession, suspendContext, threadProxy, frameProxy)
|
||||||
debuggerContext.initCaches()
|
debuggerContext.initCaches()
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
|
|||||||
|
|
||||||
private fun SuspendContextImpl.getKotlinStackFrames(): List<KotlinStackFrame> {
|
private fun SuspendContextImpl.getKotlinStackFrames(): List<KotlinStackFrame> {
|
||||||
if (myInProgress) {
|
if (myInProgress) {
|
||||||
val proxy = frameProxy ?: return emptyList()
|
val proxy = getFrameProxy(this) ?: return emptyList()
|
||||||
return KotlinPositionManager(debugProcess)
|
return KotlinPositionManager(debugProcess)
|
||||||
.createStackFrames(StackFrameDescriptorImpl(proxy, MethodsTracker()))
|
.createStackFrames(StackFrameDescriptorImpl(proxy, MethodsTracker()))
|
||||||
.filterIsInstance<KotlinStackFrame>()
|
.filterIsInstance<KotlinStackFrame>()
|
||||||
@@ -251,7 +251,10 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
|
|||||||
return@runReadAction println("Context thread is null", ProcessOutputTypes.SYSTEM)
|
return@runReadAction println("Context thread is null", ProcessOutputTypes.SYSTEM)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sourcePosition = PositionUtil.getSourcePosition(this)
|
val sourcePosition = if (anotherThreadToFocus != null)
|
||||||
|
debugProcess.positionManager.getSourcePosition(getFrameProxy(this).location())
|
||||||
|
else
|
||||||
|
PositionUtil.getSourcePosition(this)
|
||||||
println(sourcePosition?.render() ?: "null", ProcessOutputTypes.SYSTEM)
|
println(sourcePosition?.render() ?: "null", ProcessOutputTypes.SYSTEM)
|
||||||
extraPrintContext(this)
|
extraPrintContext(this)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user