mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
(CoroutineDebugger) PreflightFrame support in tests via CoroutineAsync
Original commit: 6f42ed7248a70dad12f281c2f9178288c2ad3430 GitOrigin-RevId: 8c26a8ed363d573d7e556a6541407ed79a420c8b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
03c80d1993
commit
78bd98360f
@@ -41,9 +41,15 @@ class CoroutineAsyncStackTraceProvider : AsyncStackTraceProvider {
|
||||
)
|
||||
) {
|
||||
val doubleFrameList = CoroutineFrameBuilder.build(preflightFrame, suspendContext)
|
||||
return doubleFrameList.stackTrace + doubleFrameList.creationStackTrace
|
||||
val resultList = doubleFrameList.stackTrace + doubleFrameList.creationStackTrace
|
||||
return PreflightProvider(preflightFrame, resultList)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class PreflightProvider(private val preflight: CoroutinePreflightStackFrame, stackFrames: List<CoroutineStackFrameItem>) :
|
||||
List<CoroutineStackFrameItem> by stackFrames {
|
||||
fun getPreflight() =
|
||||
preflight
|
||||
}
|
||||
@@ -25,34 +25,6 @@ import java.io.StringWriter
|
||||
|
||||
abstract class AbstractContinuationStackTraceTest : KotlinDescriptorTestCaseWithStackFrames() {
|
||||
override fun doMultiFileTest(files: TestFiles, preferences: DebuggerPreferences) {
|
||||
val asyncStackTraceProvider = getAsyncStackTraceProvider()
|
||||
|
||||
doWhenXSessionPausedThenResume {
|
||||
printContext(debugProcess.debuggerContext)
|
||||
val suspendContext = debuggerSession.xDebugSession?.getSuspendContext()
|
||||
var executionStack = suspendContext?.getActiveExecutionStack()
|
||||
if (executionStack != null) {
|
||||
try {
|
||||
out("Thread stack trace:")
|
||||
val stackFrames: List<XStackFrame> = XDebuggerTestUtil.collectFrames(executionStack)
|
||||
for (frame in stackFrames) {
|
||||
if (frame is JavaStackFrame) {
|
||||
out(frame)
|
||||
asyncStackTraceProvider?.getAsyncStackTrace(frame, suspendContext as SuspendContextImpl)?.let {
|
||||
for (frameItem in it)
|
||||
out(frameItem)
|
||||
return@doWhenXSessionPausedThenResume
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
val stackTrace = e.stackTraceAsString()
|
||||
System.err.println("Exception occurred on calculating async stack traces: $stackTrace")
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
println("FrameProxy is 'null', can't calculate async stack trace", ProcessOutputTypes.SYSTEM)
|
||||
}
|
||||
}
|
||||
printStackFrame(files, preferences)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,39 +9,12 @@ import com.intellij.debugger.engine.JavaStackFrame
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.execution.process.ProcessOutputTypes
|
||||
import com.intellij.xdebugger.frame.XStackFrame
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.PreflightProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.XDebuggerTestUtil
|
||||
|
||||
abstract class AbstractXCoroutinesStackTraceTest : KotlinDescriptorTestCaseWithStackFrames() {
|
||||
override fun doMultiFileTest(files: TestFiles, preferences: DebuggerPreferences) {
|
||||
val asyncStackTraceProvider = getAsyncStackTraceProvider()
|
||||
|
||||
doWhenXSessionPausedThenResume {
|
||||
printContext(debugProcess.debuggerContext)
|
||||
val suspendContext = debuggerSession.xDebugSession?.getSuspendContext()
|
||||
var executionStack = suspendContext?.getActiveExecutionStack()
|
||||
if (executionStack != null) {
|
||||
try {
|
||||
out("Thread stack trace:")
|
||||
val stackFrames: List<XStackFrame> = XDebuggerTestUtil.collectFrames(executionStack)
|
||||
for (frame in stackFrames) {
|
||||
if (frame is JavaStackFrame) {
|
||||
out(frame)
|
||||
asyncStackTraceProvider?.getAsyncStackTrace(frame, suspendContext as SuspendContextImpl)?.let {
|
||||
for (frameItem in it)
|
||||
out(frameItem)
|
||||
return@doWhenXSessionPausedThenResume
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
val stackTrace = e.stackTraceAsString()
|
||||
System.err.println("Exception occurred on calculating async stack traces: $stackTrace")
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
println("FrameProxy is 'null', can't calculate async stack trace", ProcessOutputTypes.SYSTEM)
|
||||
}
|
||||
}
|
||||
printStackFrame(files, preferences)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.debugger.test
|
||||
|
||||
import com.intellij.debugger.engine.AsyncStackTraceProvider
|
||||
import com.intellij.debugger.engine.JavaStackFrame
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.debugger.memory.utils.StackFrameItem
|
||||
import com.intellij.execution.configurations.JavaParameters
|
||||
import com.intellij.execution.process.ProcessOutputTypes
|
||||
@@ -22,9 +23,11 @@ import com.intellij.xdebugger.frame.XStackFrame
|
||||
import org.jetbrains.idea.maven.aether.ArtifactKind
|
||||
import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineAsyncStackTraceProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.PreflightProvider
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CreationCoroutineStackFrameItem
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.format
|
||||
import org.jetbrains.kotlin.idea.debugger.invokeInManagerThread
|
||||
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.XDebuggerTestUtil
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.test.testFramework.runWriteAction
|
||||
@@ -78,6 +81,44 @@ abstract class KotlinDescriptorTestCaseWithStackFrames() : KotlinDescriptorTestC
|
||||
return writer.toString()
|
||||
}
|
||||
|
||||
fun printStackFrame(files: TestFiles, preferences: DebuggerPreferences) {
|
||||
val asyncStackTraceProvider = getAsyncStackTraceProvider()
|
||||
|
||||
doWhenXSessionPausedThenResume {
|
||||
printContext(debugProcess.debuggerContext)
|
||||
val suspendContext = debuggerSession.xDebugSession?.getSuspendContext()
|
||||
var executionStack = suspendContext?.getActiveExecutionStack()
|
||||
if (executionStack != null) {
|
||||
try {
|
||||
out("Thread stack trace:")
|
||||
val stackFrames: List<XStackFrame> = XDebuggerTestUtil.collectFrames(executionStack)
|
||||
for (frame in stackFrames) {
|
||||
if (frame is JavaStackFrame) {
|
||||
out(frame)
|
||||
val stackFrames = asyncStackTraceProvider?.getAsyncStackTrace(frame, suspendContext as SuspendContextImpl)
|
||||
if (stackFrames != null) {
|
||||
if (stackFrames is PreflightProvider) {
|
||||
val preflightFrame = stackFrames.getPreflight()
|
||||
out(0, preflightFrame.coroutineInfoData.key.toString())
|
||||
}
|
||||
for (frameItem in stackFrames)
|
||||
out(frameItem)
|
||||
return@doWhenXSessionPausedThenResume
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
val stackTrace = e.stackTraceAsString()
|
||||
System.err.println("Exception occurred on calculating async stack traces: $stackTrace")
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
println("FrameProxy is 'null', can't calculate async stack trace", ProcessOutputTypes.SYSTEM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected fun getAsyncStackTraceProvider(): CoroutineAsyncStackTraceProvider? {
|
||||
val area = Extensions.getArea(null)
|
||||
if (!area.hasExtensionPoint(ASYNC_STACKTRACE_EP_NAME)) {
|
||||
@@ -143,4 +184,4 @@ abstract class KotlinDescriptorTestCaseWithStackFrames() : KotlinDescriptorTestC
|
||||
RemoteRepositoryDescription.DEFAULT_REPOSITORIES, null
|
||||
) ?: throw AssertionError("Maven Dependency not found: $description")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,17 @@ fun main() {
|
||||
suspend fun test1(i: Int): Int {
|
||||
val test1 = "a"
|
||||
a(test1)
|
||||
println(test1)
|
||||
return i
|
||||
}
|
||||
|
||||
suspend fun a(aParam: String) {
|
||||
val a = "a"
|
||||
b(a)
|
||||
println(a)
|
||||
a + 1
|
||||
}
|
||||
|
||||
suspend fun b(bParam: String) {
|
||||
val b = "b"
|
||||
// Breakpoint!
|
||||
println(b)
|
||||
//Breakpoint!
|
||||
b + 1
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
LineBreakpoint created at suspendFun.kt:28
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
suspendFun.kt:28
|
||||
Thread stack trace:
|
||||
b:28, SuspendFunKt (coroutine1)
|
||||
($completion, b, bParam)
|
||||
a:21, SuspendFunKt (coroutine1)
|
||||
($completion, $continuation, $result, a, aParam)
|
||||
test1:15, SuspendFunKt (coroutine1)
|
||||
($completion, $continuation, $result, i, test1)
|
||||
invoke:9, SuspendFunKt$main$result$1 (coroutine1)
|
||||
(continuation, p1, this)
|
||||
invoke:-1, SuspendFunKt$main$result$1 (coroutine1)
|
||||
(this)
|
||||
invokeSuspend:121, IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3 (kotlin.coroutines.intrinsics)
|
||||
($i$a$-createCoroutineFromSuspendFunction-IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$2, it, result, this)
|
||||
resumeWith:33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
|
||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||
startCoroutine:128, ContinuationKt (kotlin.coroutines)
|
||||
($this$startCoroutine, completion, receiver)
|
||||
main:9, SuspendFunKt (coroutine1)
|
||||
(cnt)
|
||||
main:-1, SuspendFunKt (coroutine1)
|
||||
()
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
kotlin.Unit
|
||||
@@ -1,12 +1,13 @@
|
||||
LineBreakpoint created at sequence.kt:14
|
||||
LineBreakpoint created at suspendLambda.kt:12
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
sequence.kt:12
|
||||
suspendLambda.kt:12
|
||||
Thread stack trace:
|
||||
nextSequence:12, SequenceKt (continuation)
|
||||
nextSequence:12, SuspendLambdaKt (continuation)
|
||||
(terms, terms1)
|
||||
invokeSuspend:23, SequenceKt$fibonacci$1 (continuation)
|
||||
invokeSuspend:23, SuspendLambdaKt$fibonacci$1 (continuation)
|
||||
($result, $this$sequence, step, terms, this)
|
||||
CoroutineNameIdState(name=coroutine, id=-1, state=UNKNOWN, dispatcher=null)
|
||||
resumeWith:33, kotlin.coroutines.jvm.internal.BaseContinuationImpl
|
||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||
hasNext:140, kotlin.sequences.SequenceBuilderIterator
|
||||
@@ -19,9 +20,9 @@ Thread stack trace:
|
||||
($this$toMutableList)
|
||||
toList:743, kotlin.sequences.SequencesKt___SequencesKt
|
||||
($this$toList)
|
||||
main:5, continuation.SequenceKt
|
||||
main:5, continuation.SuspendLambdaKt
|
||||
(a)
|
||||
main:-1, continuation.SequenceKt
|
||||
main:-1, continuation.SuspendLambdaKt
|
||||
()
|
||||
Disconnected from the target VM
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
LineBreakpoint created at coroutineSuspendFun.kt:30
|
||||
LineBreakpoint created at coroutineSuspendFun.kt:29
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
coroutineSuspendFun.kt:30
|
||||
coroutineSuspendFun.kt:29
|
||||
Thread stack trace:
|
||||
c:30, CoroutineSuspendFunKt (continuation)
|
||||
c:29, CoroutineSuspendFunKt (continuation)
|
||||
($completion, c, paramB)
|
||||
b:24, CoroutineSuspendFunKt (continuation)
|
||||
b:23, CoroutineSuspendFunKt (continuation)
|
||||
($completion, $continuation, $result, b, paramA)
|
||||
a:17, continuation.CoroutineSuspendFunKt
|
||||
CoroutineNameIdState(name=coroutine, id=1, state=RUNNING, dispatcher=BlockingEventLoop@6f45df59)
|
||||
a:16, continuation.CoroutineSuspendFunKt
|
||||
(a)
|
||||
invokeSuspend:11, continuation.CoroutineSuspendFunKt$main$1
|
||||
invokeSuspend:10, continuation.CoroutineSuspendFunKt$main$1
|
||||
($this$runBlocking)
|
||||
resumeWith:33, kotlin.coroutines.jvm.internal.BaseContinuationImpl
|
||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||
@@ -27,7 +28,7 @@ Thread stack trace:
|
||||
()
|
||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
||||
()
|
||||
main:10, continuation.CoroutineSuspendFunKt
|
||||
main:9, continuation.CoroutineSuspendFunKt
|
||||
(main)
|
||||
main:-1, continuation.CoroutineSuspendFunKt
|
||||
()
|
||||
@@ -38,7 +39,7 @@ Creation stack frame
|
||||
()
|
||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
||||
()
|
||||
main:10, continuation.CoroutineSuspendFunKt
|
||||
main:9, continuation.CoroutineSuspendFunKt
|
||||
()
|
||||
main:-1, continuation.CoroutineSuspendFunKt
|
||||
()
|
||||
|
||||
Reference in New Issue
Block a user