mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
[debugger] Introduce a way to provide evaluationContext without converting it to pausedContext
GitOrigin-RevId: 0b640745949259f4054467cbf047201c97838bc5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b4a3c40497
commit
3edbfaa5d0
@@ -2,8 +2,10 @@
|
|||||||
package com.intellij.debugger.engine;
|
package com.intellij.debugger.engine;
|
||||||
|
|
||||||
import com.intellij.debugger.*;
|
import com.intellij.debugger.*;
|
||||||
|
import com.intellij.debugger.engine.evaluation.DebuggerImplicitEvaluationContextUtil;
|
||||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
||||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||||
|
import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
|
||||||
import com.intellij.debugger.engine.requests.CustomProcessingLocatableEventRequestor;
|
import com.intellij.debugger.engine.requests.CustomProcessingLocatableEventRequestor;
|
||||||
import com.intellij.debugger.engine.requests.LocatableEventRequestor;
|
import com.intellij.debugger.engine.requests.LocatableEventRequestor;
|
||||||
import com.intellij.debugger.engine.requests.MethodReturnValueWatcher;
|
import com.intellij.debugger.engine.requests.MethodReturnValueWatcher;
|
||||||
@@ -283,7 +285,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
//((SuspendManagerImpl)getSuspendManager()).popContext(context);
|
//((SuspendManagerImpl)getSuspendManager()).popContext(context);
|
||||||
}
|
}
|
||||||
else if (!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
else if (!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
||||||
notifySkippedBreakpointInEvaluation(locatableEvent);
|
notifySkippedBreakpointInEvaluation(locatableEvent, context);
|
||||||
DebuggerUtilsAsync.resume(eventSet);
|
DebuggerUtilsAsync.resume(eventSet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -642,7 +644,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
if ((isEvaluationOnCurrentThread || mySuspendAllInvocation.get() > 0) &&
|
if ((isEvaluationOnCurrentThread || mySuspendAllInvocation.get() > 0) &&
|
||||||
!(requestor instanceof InstrumentationTracker.InstrumentationMethodBreakpoint) &&
|
!(requestor instanceof InstrumentationTracker.InstrumentationMethodBreakpoint) &&
|
||||||
!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
!DebuggerSession.enableBreakpointsDuringEvaluation()) {
|
||||||
notifySkippedBreakpointInEvaluation(event);
|
notifySkippedBreakpointInEvaluation(event, suspendContext);
|
||||||
// is inside evaluation, so ignore any breakpoints
|
// is inside evaluation, so ignore any breakpoints
|
||||||
suspendManager.voteResume(suspendContext);
|
suspendManager.voteResume(suspendContext);
|
||||||
return;
|
return;
|
||||||
@@ -658,7 +660,10 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
LightOrRealThreadInfo filter = getRequestsManager().getFilterThread();
|
LightOrRealThreadInfo filter = getRequestsManager().getFilterThread();
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
if (myPreparingToSuspendAll || !filter.checkSameThread(thread, suspendContext)) {
|
if (myPreparingToSuspendAll || !filter.checkSameThread(thread, suspendContext)) {
|
||||||
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
// notify only if the current session is not one with evaluations hidden from the user
|
||||||
|
if (!checkContextIsFromImplicitThread(suspendContext)) {
|
||||||
|
notifySkippedBreakpoints(event, SkippedBreakpointReason.STEPPING);
|
||||||
|
}
|
||||||
suspendManager.voteResume(suspendContext);
|
suspendManager.voteResume(suspendContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -836,7 +841,12 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
STEPPING, // Suspend-all stepping ignores breakpoints in other threads for the sake of ease-of-debug.
|
STEPPING, // Suspend-all stepping ignores breakpoints in other threads for the sake of ease-of-debug.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySkippedBreakpointInEvaluation(@Nullable LocatableEvent event) {
|
private void notifySkippedBreakpointInEvaluation(@Nullable LocatableEvent event, @NotNull SuspendContextImpl suspendContext) {
|
||||||
|
// notify only if the current session is not one with evaluations hidden from the user
|
||||||
|
if (checkContextIsFromImplicitThread(suspendContext)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SkippedBreakpointReason reason = SkippedBreakpointReason.EVALUATION_IN_ANOTHER_THREAD;
|
SkippedBreakpointReason reason = SkippedBreakpointReason.EVALUATION_IN_ANOTHER_THREAD;
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
ThreadReferenceProxyImpl proxy = getVirtualMachineProxy().getThreadReferenceProxy(event.thread());
|
ThreadReferenceProxyImpl proxy = getVirtualMachineProxy().getThreadReferenceProxy(event.thread());
|
||||||
@@ -847,6 +857,25 @@ public class DebugProcessEvents extends DebugProcessImpl {
|
|||||||
notifySkippedBreakpoints(event, reason);
|
notifySkippedBreakpoints(event, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkContextIsFromImplicitThread(@NotNull SuspendContextImpl eventContext) {
|
||||||
|
DebugProcess debugProcess = eventContext.getDebugProcess();
|
||||||
|
LightOrRealThreadInfo implicitThread = DebuggerImplicitEvaluationContextUtil.getImplicitEvaluationThread(debugProcess);
|
||||||
|
LightOrRealThreadInfo filterThread = getRequestsManager().getFilterThread();
|
||||||
|
ThreadReferenceProxy eventThread = eventContext.getThread();
|
||||||
|
|
||||||
|
if (implicitThread == null || eventThread == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 1: We have filter and implicit threads provided, they are different, hence, this skipped breakpoint is no use for the user
|
||||||
|
if (filterThread != null && !implicitThread.checkSameThread(eventThread.getThreadReference(), eventContext)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Implicit thread is provided, no filter thread, check correct hit
|
||||||
|
return implicitThread.checkSameThread(eventThread.getThreadReference(), eventContext);
|
||||||
|
}
|
||||||
|
|
||||||
private void notifySkippedBreakpoints(@Nullable LocatableEvent event, SkippedBreakpointReason reason) {
|
private void notifySkippedBreakpoints(@Nullable LocatableEvent event, SkippedBreakpointReason reason) {
|
||||||
if (event == null) return;
|
if (event == null) return;
|
||||||
|
|
||||||
|
|||||||
@@ -2604,7 +2604,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEvaluationPossible() {
|
public boolean isEvaluationPossible() {
|
||||||
return getSuspendManager().getPausedContext() != null;
|
return getSuspendManager().getPausedContext() != null
|
||||||
|
|| DebuggerImplicitEvaluationContextUtil.getImplicitEvaluationThread(this) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEvaluationPossible(SuspendContextImpl suspendContext) {
|
public boolean isEvaluationPossible(SuspendContextImpl suspendContext) {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// 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.evaluation;
|
||||||
|
|
||||||
|
import com.intellij.debugger.engine.DebugProcess;
|
||||||
|
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||||
|
import com.intellij.debugger.engine.LightOrRealThreadInfo;
|
||||||
|
import com.intellij.openapi.util.Key;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for providing an implicit evaluation-ready {@link LightOrRealThreadInfo} for a particular {@link DebugProcess}.
|
||||||
|
* This might be useful to support evaluations in the current {@link com.intellij.debugger.impl.DebuggerSession},
|
||||||
|
* but keeping any UI elements hidden.
|
||||||
|
* <p>
|
||||||
|
* {@link DebugProcessImpl#isEvaluationPossible()}
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public final class DebuggerImplicitEvaluationContextUtil {
|
||||||
|
private static final Key<LightOrRealThreadInfo> IMPLICIT_EVALUATION_READY_THREAD_KEY = new Key<>("ImplicitEvaluationThread");
|
||||||
|
|
||||||
|
public static LightOrRealThreadInfo getImplicitEvaluationThread(DebugProcess process) {
|
||||||
|
return process.getUserData(IMPLICIT_EVALUATION_READY_THREAD_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void provideImplicitEvaluationThread(DebugProcess process, LightOrRealThreadInfo thread) {
|
||||||
|
process.putUserData(IMPLICIT_EVALUATION_READY_THREAD_KEY, thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user