diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index 3b68939323db..58d126b6ec08 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -18,10 +18,7 @@ import com.intellij.debugger.requests.Requestor; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.statistics.DebuggerStatistics; import com.intellij.debugger.statistics.StatisticsStorage; -import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.InstrumentationTracker; -import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint; -import com.intellij.debugger.ui.breakpoints.SyntheticBreakpoint; +import com.intellij.debugger.ui.breakpoints.*; import com.intellij.debugger.ui.overhead.OverheadProducer; import com.intellij.debugger.ui.overhead.OverheadTimings; import com.intellij.ide.BrowserUtil; @@ -646,6 +643,22 @@ public class DebugProcessEvents extends DebugProcessImpl { final SuspendManager suspendManager = getSuspendManager(); final LocatableEventRequestor requestor = (LocatableEventRequestor)RequestManagerImpl.findRequestor(event.request()); + + boolean isDebugLogBreakpoint = requestor instanceof InternalDebugLoggingRequestor dReq && dReq.isDebugLogBreakpoint(); + + if (isDebugLogBreakpoint) { + String firstArgument; + try { + firstArgument = suspendContext.getEventThread().frame(0).getArgumentValues().get(0).toString(); + } + catch (Throwable e) { + firstArgument = e.getMessage(); + } + LOG.debug("Debug log breakpoint: " + firstArgument); + suspendManager.voteResume(suspendContext); + return; + } + ThreadReferenceProxyImpl threadProxy = suspendContext.getThread(); boolean isEvaluationOnCurrentThread = threadProxy != null && threadProxy.isEvaluating(); if ((isEvaluationOnCurrentThread || myThreadBlockedMonitor.isInResumeAllMode()) && diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index ea1ca3b78d1d..93a57a6562f1 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -75,7 +75,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Stream; -public abstract class Breakpoint
implements FilteredRequestor, ClassPrepareRequestor, OverheadProducer { +public abstract class Breakpoint
implements FilteredRequestor, ClassPrepareRequestor, OverheadProducer, InternalDebugLoggingRequestor {
public static final Key implements
@NonNls private static final String LOG_MESSAGE_OPTION_NAME = "LOG_MESSAGE";
protected boolean myCachedVerifiedState = false;
+ private boolean myIsDebugLogBreakpoint;
+
protected Breakpoint(@NotNull Project project, XBreakpoint xBreakpoint) {
myProject = project;
myXBreakpoint = xBreakpoint;
@@ -810,4 +812,13 @@ public abstract class Breakpoint implements
protected void fireBreakpointChanged() {
((XBreakpointBase, ?, ?>)myXBreakpoint).fireBreakpointChanged();
}
+
+ public void setIsDebugLogBreakpoint(boolean isDebugLogBreakpoint) {
+ myIsDebugLogBreakpoint = isDebugLogBreakpoint;
+ }
+
+ @Override
+ public boolean isDebugLogBreakpoint() {
+ return myIsDebugLogBreakpoint;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/InternalDebugLoggingRequestor.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/InternalDebugLoggingRequestor.java
new file mode 100644
index 000000000000..8cc58ce2ad5a
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/InternalDebugLoggingRequestor.java
@@ -0,0 +1,12 @@
+// 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.ui.breakpoints;
+
+import org.jetbrains.annotations.ApiStatus;
+
+/** It is used to investigate flaky test behavior in complex cases */
+@ApiStatus.Internal
+public interface InternalDebugLoggingRequestor {
+ default boolean isDebugLogBreakpoint() {
+ return false;
+ }
+}
diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/stepping/CoroutineBreakpointFacility.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/stepping/CoroutineBreakpointFacility.kt
index f1f25d368a37..36870170e971 100644
--- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/stepping/CoroutineBreakpointFacility.kt
+++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/stepping/CoroutineBreakpointFacility.kt
@@ -106,8 +106,7 @@ object CoroutineBreakpointFacility {
breakpoint.createRequest(debugProcess)
debugProcess.setSteppingBreakpoint(breakpoint)
- val filterThread = debugProcess.requestsManager.filterThread
- thisLogger().debug("Resume breakpoint for $method in thread $filterThread")
+ thisLogger().debug("Resume breakpoint for $method in context $context")
return true
}
diff --git a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/util/BreakpointCreator.kt b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/util/BreakpointCreator.kt
index 4db24f82a2bb..3020cc1dfb4d 100644
--- a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/util/BreakpointCreator.kt
+++ b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/util/BreakpointCreator.kt
@@ -2,16 +2,14 @@
package org.jetbrains.kotlin.idea.debugger.test.util
-import com.intellij.debugger.DebuggerInvocationUtil
import com.intellij.debugger.engine.evaluation.CodeFragmentKind
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
import com.intellij.debugger.ui.breakpoints.Breakpoint
import com.intellij.debugger.ui.breakpoints.BreakpointManager
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType
import com.intellij.debugger.ui.breakpoints.LineBreakpoint
-import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.runReadAction
-import com.intellij.openapi.application.runWriteAction
+import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.VirtualFile
@@ -27,6 +25,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointType
import com.intellij.xdebugger.breakpoints.XLineBreakpointType
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties
+import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
import org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType
import org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointType
import org.jetbrains.kotlin.idea.debugger.core.DebuggerUtils.isKotlinSourceFile
@@ -35,9 +34,7 @@ import org.jetbrains.kotlin.idea.debugger.core.breakpoints.KotlinFunctionBreakpo
import org.jetbrains.kotlin.idea.debugger.core.breakpoints.KotlinFunctionBreakpointType
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferenceKeys
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
-import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
import java.util.*
-import javax.swing.SwingUtilities
internal class BreakpointCreator(
private val project: Project,
@@ -94,6 +91,9 @@ internal class BreakpointCreator(
comment.startsWith("//FunctionBreakpoint!") -> {
createFunctionBreakpoint(breakpointManager, file, lineIndex, false)
}
+ comment.startsWith("//LogFirstArgumentBreakpoint!") -> {
+ createLogFirstArgumentBreakpoint(breakpointManager, file, lineIndex)
+ }
else -> throw AssertionError("Cannot create breakpoint at line ${lineIndex + 1}")
}
}
@@ -171,6 +171,22 @@ internal class BreakpointCreator(
}
}
+ private fun createLogFirstArgumentBreakpoint(breakpointManager: XBreakpointManager, file: PsiFile, lineIndex: Int) {
+ val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
+ val javaBreakpoint = createBreakpointOfType(
+ breakpointManager,
+ kotlinLineBreakpointType,
+ lineIndex,
+ file.virtualFile,
+ null,
+ false,
+ )
+ javaBreakpoint?.setIsDebugLogBreakpoint(true)
+ if (javaBreakpoint is LineBreakpoint<*>) {
+ thisLogger().debug("LogFirstArgumentBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}")
+ }
+ }
+
private fun createLineBreakpoint(
breakpointManager: XBreakpointManager,
file: PsiFile,
diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.kt
index 45af75b5031d..21b997bbfeb7 100644
--- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.kt
+++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.kt
@@ -5,10 +5,12 @@ import kotlinx.coroutines.*
suspend fun foo(i: Int) {
println("Start foo")
coroutineScope {
+ trackExecution("Start for $i")
if (i == 25) {
//Breakpoint!
startMethod(i)
}
+ trackExecution("Middle for $i")
delay(1)
// EXPRESSION: i
// RESULT: 25: I
@@ -39,7 +41,13 @@ fun main() {
}
}
-// STEP_OVER: 3
+fun trackExecution(s: String) {
+ //LogFirstArgumentBreakpoint!
+ s.toString()
+}
+
+
+// STEP_OVER: 4
// REGISTRY: debugger.filter.breakpoints.by.coroutine.id=true
// REGISTRY: debugger.always.suspend.thread.before.switch=true
// REGISTRY: debugger.log.jdi.in.unit.tests=true
diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.out b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.out
index 8b6858582e7d..6533b9c4ec34 100644
--- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.out
+++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/stepOver/stepThroughCoroutineScope.out
@@ -1,10 +1,11 @@
-LineBreakpoint created at stepThroughCoroutineScope.kt:10
+LineBreakpoint created at stepThroughCoroutineScope.kt:11
Run Java
Connected to the target VM
-stepThroughCoroutineScope.kt:10
-stepThroughCoroutineScope.kt:12
-stepThroughCoroutineScope.kt:15
-stepThroughCoroutineScope.kt:16
+stepThroughCoroutineScope.kt:11
+stepThroughCoroutineScope.kt:13
+stepThroughCoroutineScope.kt:14
+stepThroughCoroutineScope.kt:17
+stepThroughCoroutineScope.kt:18
Compile bytecode for i
Disconnected from the target VM