(CoroutineDebugger) PreflightFrame support in tests via CoroutineAsync

Original commit: 6f42ed7248a70dad12f281c2f9178288c2ad3430

GitOrigin-RevId: 8c26a8ed363d573d7e556a6541407ed79a420c8b
This commit is contained in:
Vladimir Ilmov
2020-04-19 12:38:45 +02:00
committed by intellij-monorepo-bot
parent 03c80d1993
commit 78bd98360f
8 changed files with 100 additions and 78 deletions

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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")
}
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
()