(CoroutineDebugger) Minor fixes, kotlinx.coroutines version fix
This commit is contained in:
+20
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.idea.debugger
|
|||||||
|
|
||||||
import com.intellij.debugger.engine.DebugProcessImpl
|
import com.intellij.debugger.engine.DebugProcessImpl
|
||||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
|
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
|
||||||
|
import com.intellij.debugger.engine.SuspendContextImpl
|
||||||
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.impl.DebuggerContextImpl
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.sun.jdi.*
|
import com.sun.jdi.*
|
||||||
@@ -84,6 +86,24 @@ fun <T : Any> DebugProcessImpl.invokeInManagerThread(f: (DebuggerContextImpl) ->
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T : Any> SuspendContextImpl.invokeInSuspendManagerThread(debugProcessImpl: DebugProcessImpl, f: (SuspendContextImpl) -> T?): T? {
|
||||||
|
var result: T? = null
|
||||||
|
val command: SuspendContextCommandImpl = object : SuspendContextCommandImpl(this) {
|
||||||
|
override fun contextAction() {
|
||||||
|
result = runReadAction { f(this@invokeInSuspendManagerThread) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
DebuggerManagerThreadImpl.isManagerThread() ->
|
||||||
|
debugProcessImpl.managerThread.invoke(command)
|
||||||
|
else ->
|
||||||
|
debugProcessImpl.managerThread.invokeAndWait(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
private fun lambdaOrdinalByArgument(elementAt: KtFunction, context: BindingContext): Int {
|
private fun lambdaOrdinalByArgument(elementAt: KtFunction, context: BindingContext): Int {
|
||||||
val type = asmTypeForAnonymousClass(context, elementAt)
|
val type = asmTypeForAnonymousClass(context, elementAt)
|
||||||
return type.className.substringAfterLast("$").toInt()
|
return type.className.substringAfterLast("$").toInt()
|
||||||
|
|||||||
+8
-11
@@ -6,10 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.idea.debugger.coroutine
|
package org.jetbrains.kotlin.idea.debugger.coroutine
|
||||||
|
|
||||||
import com.intellij.debugger.DebuggerInvocationUtil
|
import com.intellij.debugger.DebuggerInvocationUtil
|
||||||
import com.intellij.debugger.engine.DebugProcessImpl
|
|
||||||
import com.intellij.debugger.engine.JavaDebugProcess
|
import com.intellij.debugger.engine.JavaDebugProcess
|
||||||
import com.intellij.debugger.engine.SuspendContextImpl
|
import com.intellij.debugger.engine.SuspendContextImpl
|
||||||
import com.intellij.debugger.impl.PrioritizedTask
|
|
||||||
import com.intellij.execution.configurations.DebuggingRunnerData
|
import com.intellij.execution.configurations.DebuggingRunnerData
|
||||||
import com.intellij.execution.configurations.JavaParameters
|
import com.intellij.execution.configurations.JavaParameters
|
||||||
import com.intellij.execution.configurations.RunConfigurationBase
|
import com.intellij.execution.configurations.RunConfigurationBase
|
||||||
@@ -18,7 +16,6 @@ import com.intellij.execution.ui.layout.PlaceInGrid
|
|||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.openapi.util.registry.Registry
|
|
||||||
import com.intellij.ui.content.Content
|
import com.intellij.ui.content.Content
|
||||||
import com.intellij.util.messages.MessageBusConnection
|
import com.intellij.util.messages.MessageBusConnection
|
||||||
import com.intellij.xdebugger.XDebugProcess
|
import com.intellij.xdebugger.XDebugProcess
|
||||||
@@ -49,15 +46,15 @@ class DebuggerConnection(
|
|||||||
val kotlinxCoroutinesDebug = params.classPath?.pathList?.firstOrNull { it.contains("kotlinx-coroutines-debug") }
|
val kotlinxCoroutinesDebug = params.classPath?.pathList?.firstOrNull { it.contains("kotlinx-coroutines-debug") }
|
||||||
|
|
||||||
val mode = if (kotlinxCoroutinesDebug != null) {
|
val mode = if (kotlinxCoroutinesDebug != null) {
|
||||||
CoroutineDebuggerMode.VERSION_UP_TO_1_3_4
|
CoroutineDebuggerMode.VERSION_UP_TO_1_3_5
|
||||||
} else if (kotlinxCoroutinesCore != null) {
|
} else if (kotlinxCoroutinesCore != null) {
|
||||||
determineCoreVersionMode(kotlinxCoroutinesCore)
|
determineCoreVersionMode(kotlinxCoroutinesCore)
|
||||||
} else
|
} else
|
||||||
CoroutineDebuggerMode.DISABLED
|
CoroutineDebuggerMode.DISABLED
|
||||||
|
|
||||||
when (mode) {
|
when (mode) {
|
||||||
CoroutineDebuggerMode.VERSION_1_3_5_AND_UP -> initializeCoroutineAgent(params, kotlinxCoroutinesCore)
|
CoroutineDebuggerMode.VERSION_1_3_6_AND_UP -> initializeCoroutineAgent(params, kotlinxCoroutinesCore)
|
||||||
CoroutineDebuggerMode.VERSION_UP_TO_1_3_4 -> initializeCoroutineAgent(params, kotlinxCoroutinesDebug)
|
CoroutineDebuggerMode.VERSION_UP_TO_1_3_5 -> initializeCoroutineAgent(params, kotlinxCoroutinesDebug)
|
||||||
else -> log.debug("CoroutineDebugger disabled.")
|
else -> log.debug("CoroutineDebugger disabled.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,9 +66,9 @@ class DebuggerConnection(
|
|||||||
val matchResult = regex.matchEntire(kotlinxCoroutinesCore) ?: return CoroutineDebuggerMode.DISABLED
|
val matchResult = regex.matchEntire(kotlinxCoroutinesCore) ?: return CoroutineDebuggerMode.DISABLED
|
||||||
|
|
||||||
val coroutinesCoreVersion = DefaultArtifactVersion(matchResult.groupValues.get(1))
|
val coroutinesCoreVersion = DefaultArtifactVersion(matchResult.groupValues.get(1))
|
||||||
val versionToCompareTo = DefaultArtifactVersion("1.3.4")
|
val versionToCompareTo = DefaultArtifactVersion("1.3.5")
|
||||||
return if (versionToCompareTo.compareTo(coroutinesCoreVersion) < 0)
|
return if (versionToCompareTo.compareTo(coroutinesCoreVersion) < 0)
|
||||||
CoroutineDebuggerMode.VERSION_1_3_5_AND_UP
|
CoroutineDebuggerMode.VERSION_1_3_6_AND_UP
|
||||||
else
|
else
|
||||||
CoroutineDebuggerMode.DISABLED
|
CoroutineDebuggerMode.DISABLED
|
||||||
}
|
}
|
||||||
@@ -96,7 +93,7 @@ class DebuggerConnection(
|
|||||||
override fun processStopped(debugProcess: XDebugProcess) {
|
override fun processStopped(debugProcess: XDebugProcess) {
|
||||||
val rootDisposable = disposable
|
val rootDisposable = disposable
|
||||||
if (rootDisposable is Disposable && debugProcess is JavaDebugProcess && debugProcess.session.suspendContext is SuspendContextImpl) {
|
if (rootDisposable is Disposable && debugProcess is JavaDebugProcess && debugProcess.session.suspendContext is SuspendContextImpl) {
|
||||||
ManagerThreadExecutor(debugProcess).on(debugProcess.session.suspendContext).schedule {
|
ManagerThreadExecutor(debugProcess).on(debugProcess.session.suspendContext).invoke {
|
||||||
Disposer.dispose(rootDisposable)
|
Disposer.dispose(rootDisposable)
|
||||||
disposable = null
|
disposable = null
|
||||||
}
|
}
|
||||||
@@ -124,6 +121,6 @@ class DebuggerConnection(
|
|||||||
|
|
||||||
enum class CoroutineDebuggerMode {
|
enum class CoroutineDebuggerMode {
|
||||||
DISABLED,
|
DISABLED,
|
||||||
VERSION_UP_TO_1_3_4,
|
VERSION_UP_TO_1_3_5,
|
||||||
VERSION_1_3_5_AND_UP
|
VERSION_1_3_6_AND_UP
|
||||||
}
|
}
|
||||||
+4
-2
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.debugger.coroutine.data
|
|||||||
|
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
import com.sun.jdi.ThreadReference
|
import com.sun.jdi.ThreadReference
|
||||||
|
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData.Companion.DEFAULT_COROUTINE_NAME
|
||||||
|
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CoroutineInfoData.Companion.DEFAULT_COROUTINE_STATE
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.*
|
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.*
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||||
|
|
||||||
@@ -56,9 +58,9 @@ data class CoroutineNameIdState(val name: String, val id: String, val state: Sta
|
|||||||
companion object {
|
companion object {
|
||||||
fun instance(mirror: MirrorOfCoroutineInfo): CoroutineNameIdState =
|
fun instance(mirror: MirrorOfCoroutineInfo): CoroutineNameIdState =
|
||||||
CoroutineNameIdState(
|
CoroutineNameIdState(
|
||||||
mirror.context?.name ?: "coroutine",
|
mirror.context?.name ?: DEFAULT_COROUTINE_NAME,
|
||||||
"${mirror.sequenceNumber}",
|
"${mirror.sequenceNumber}",
|
||||||
State.valueOf(mirror.state ?: "UNKNOWN"),
|
State.valueOf(mirror.state ?: DEFAULT_COROUTINE_STATE),
|
||||||
mirror.context?.dispatcher
|
mirror.context?.dispatcher
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-12
@@ -49,14 +49,12 @@ class CoroutinePreflightStackFrame(
|
|||||||
|
|
||||||
override fun getVisibleVariables(): List<LocalVariableProxyImpl> {
|
override fun getVisibleVariables(): List<LocalVariableProxyImpl> {
|
||||||
// skip restored variables
|
// skip restored variables
|
||||||
return super.getVisibleVariables().filter { v -> firstFrameVariables.find { it.name == v.name() } == null }
|
return super.getVisibleVariables().filter { v -> ! firstFrameVariables.any { it.name == v.name() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isInLibraryContent() =
|
override fun isInLibraryContent() = false
|
||||||
false
|
|
||||||
|
|
||||||
override fun isSynthetic() =
|
override fun isSynthetic() = false
|
||||||
false
|
|
||||||
|
|
||||||
fun restoredStackTrace() =
|
fun restoredStackTrace() =
|
||||||
coroutineInfoData.restoredStackTrace(mode)
|
coroutineInfoData.restoredStackTrace(mode)
|
||||||
@@ -69,7 +67,7 @@ enum class SuspendExitMode {
|
|||||||
this == SUSPEND_LAMBDA || this == SUSPEND_METHOD_PARAMETER
|
this == SUSPEND_LAMBDA || this == SUSPEND_METHOD_PARAMETER
|
||||||
|
|
||||||
fun isSuspendMethodParameter() =
|
fun isSuspendMethodParameter() =
|
||||||
this == SuspendExitMode.SUSPEND_METHOD_PARAMETER
|
this == SUSPEND_METHOD_PARAMETER
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreationCoroutineStackFrame(debugProcess: DebugProcessImpl, item: StackFrameItem) : CoroutineStackFrame(debugProcess, item) {
|
class CreationCoroutineStackFrame(debugProcess: DebugProcessImpl, item: StackFrameItem) : CoroutineStackFrame(debugProcess, item) {
|
||||||
@@ -81,11 +79,7 @@ class CreationCoroutineStackFrame(debugProcess: DebugProcessImpl, item: StackFra
|
|||||||
|
|
||||||
open class CoroutineStackFrame(debugProcess: DebugProcessImpl, val item: StackFrameItem, val realStackFrame: XStackFrame? = null) :
|
open class CoroutineStackFrame(debugProcess: DebugProcessImpl, val item: StackFrameItem, val realStackFrame: XStackFrame? = null) :
|
||||||
StackFrameItem.CapturedStackFrame(debugProcess, item) {
|
StackFrameItem.CapturedStackFrame(debugProcess, item) {
|
||||||
override fun customizePresentation(component: ColoredTextContainer) {
|
|
||||||
if (coroutineDebuggerTraceEnabled())
|
|
||||||
component.append("${item.javaClass.simpleName} / ${this.javaClass.simpleName} ", SimpleTextAttributes.GRAYED_ATTRIBUTES)
|
|
||||||
super.customizePresentation(component)
|
|
||||||
}
|
|
||||||
override fun computeChildren(node: XCompositeNode) {
|
override fun computeChildren(node: XCompositeNode) {
|
||||||
if (realStackFrame != null)
|
if (realStackFrame != null)
|
||||||
realStackFrame.computeChildren(node)
|
realStackFrame.computeChildren(node)
|
||||||
@@ -93,7 +87,6 @@ open class CoroutineStackFrame(debugProcess: DebugProcessImpl, val item: StackFr
|
|||||||
super.computeChildren(node)
|
super.computeChildren(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getCaptionAboveOf() = "CoroutineExit"
|
override fun getCaptionAboveOf() = "CoroutineExit"
|
||||||
|
|
||||||
override fun hasSeparatorAbove(): Boolean =
|
override fun hasSeparatorAbove(): Boolean =
|
||||||
|
|||||||
+5
-4
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror.*
|
|||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.*
|
import org.jetbrains.kotlin.idea.debugger.coroutine.util.*
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||||
|
|
||||||
class ContinuationHolder(val context: DefaultExecutionContext) {
|
class ContinuationHolder private constructor(val context: DefaultExecutionContext) {
|
||||||
private val debugMetadata: DebugMetadata? = DebugMetadata.instance(context)
|
private val debugMetadata: DebugMetadata? = DebugMetadata.instance(context)
|
||||||
private val locationCache = LocationCache(context)
|
private val locationCache = LocationCache(context)
|
||||||
private val debugProbesImpl = DebugProbesImpl.instance(context)
|
private val debugProbesImpl = DebugProbesImpl.instance(context)
|
||||||
@@ -70,6 +70,7 @@ class ContinuationHolder(val context: DefaultExecutionContext) {
|
|||||||
val id = standAloneCoroutineMirror.context.id
|
val id = standAloneCoroutineMirror.context.id
|
||||||
val name = standAloneCoroutineMirror.context.name ?: CoroutineInfoData.DEFAULT_COROUTINE_NAME
|
val name = standAloneCoroutineMirror.context.name ?: CoroutineInfoData.DEFAULT_COROUTINE_NAME
|
||||||
val toString = reference.string(value, context)
|
val toString = reference.string(value, context)
|
||||||
|
// trying to get coroutine information by calling JobSupport.toString(), ${nameString()}{${stateString(state)}}@$hexAddress
|
||||||
val r = """\w+\{(\w+)\}\@([\w\d]+)""".toRegex()
|
val r = """\w+\{(\w+)\}\@([\w\d]+)""".toRegex()
|
||||||
val matcher = r.toPattern().matcher(toString)
|
val matcher = r.toPattern().matcher(toString)
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
@@ -94,6 +95,9 @@ class ContinuationHolder(val context: DefaultExecutionContext) {
|
|||||||
companion object {
|
companion object {
|
||||||
val log by logger
|
val log by logger
|
||||||
|
|
||||||
|
fun instance(context: DefaultExecutionContext) =
|
||||||
|
ContinuationHolder(context)
|
||||||
|
|
||||||
private fun stateOf(state: String?): State =
|
private fun stateOf(state: String?): State =
|
||||||
when (state) {
|
when (state) {
|
||||||
"Active" -> State.RUNNING
|
"Active" -> State.RUNNING
|
||||||
@@ -104,8 +108,6 @@ class ContinuationHolder(val context: DefaultExecutionContext) {
|
|||||||
"New" -> State.NEW
|
"New" -> State.NEW
|
||||||
else -> State.UNKNOWN
|
else -> State.UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,5 +131,4 @@ fun FieldVariable.toJavaValue(continuation: ObjectReference, context: DefaultExe
|
|||||||
context.debugProcess.xdebugProcess!!.nodeManager,
|
context.debugProcess.xdebugProcess!!.nodeManager,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
|||||||
class CoroutineNoLibraryProxy(val executionContext: DefaultExecutionContext) : CoroutineInfoProvider {
|
class CoroutineNoLibraryProxy(val executionContext: DefaultExecutionContext) : CoroutineInfoProvider {
|
||||||
val log by logger
|
val log by logger
|
||||||
val debugMetadataKtType = executionContext.findCoroutineMetadataType()
|
val debugMetadataKtType = executionContext.findCoroutineMetadataType()
|
||||||
val holder = ContinuationHolder(executionContext)
|
val holder = ContinuationHolder.instance(executionContext)
|
||||||
|
|
||||||
override fun dumpCoroutinesInfo(): List<CoroutineInfoData> {
|
override fun dumpCoroutinesInfo(): List<CoroutineInfoData> {
|
||||||
val vm = executionContext.vm
|
val vm = executionContext.vm
|
||||||
@@ -55,7 +55,7 @@ class CoroutineNoLibraryProxy(val executionContext: DefaultExecutionContext) : C
|
|||||||
): CoroutineInfoData? {
|
): CoroutineInfoData? {
|
||||||
val mirror = ccMirrorProvider.mirror(dispatchedContinuation, executionContext) ?: return null
|
val mirror = ccMirrorProvider.mirror(dispatchedContinuation, executionContext) ?: return null
|
||||||
val continuation = mirror.delegate?.continuation ?: return null
|
val continuation = mirror.delegate?.continuation ?: return null
|
||||||
return holder.extractCoroutineInfoData(continuation)
|
return holder?.extractCoroutineInfoData(continuation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dispatchedContinuation(resultList: MutableList<CoroutineInfoData>): Boolean {
|
private fun dispatchedContinuation(resultList: MutableList<CoroutineInfoData>): Boolean {
|
||||||
@@ -75,7 +75,7 @@ class CoroutineNoLibraryProxy(val executionContext: DefaultExecutionContext) : C
|
|||||||
private fun extractDispatchedContinuation(dispatchedContinuation: ObjectReference, continuation: Field): CoroutineInfoData? {
|
private fun extractDispatchedContinuation(dispatchedContinuation: ObjectReference, continuation: Field): CoroutineInfoData? {
|
||||||
debugMetadataKtType ?: return null
|
debugMetadataKtType ?: return null
|
||||||
val initialContinuation = dispatchedContinuation.getValue(continuation) as ObjectReference
|
val initialContinuation = dispatchedContinuation.getValue(continuation) as ObjectReference
|
||||||
return holder.extractCoroutineInfoData(initialContinuation)
|
return holder?.extractCoroutineInfoData(initialContinuation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-5
@@ -34,16 +34,18 @@ class ManagerThreadExecutor(val debugProcess: DebugProcessImpl) {
|
|||||||
|
|
||||||
constructor(sc: XSuspendContext, priority: PrioritizedTask.Priority) : this(sc as SuspendContextImpl, priority)
|
constructor(sc: XSuspendContext, priority: PrioritizedTask.Priority) : this(sc as SuspendContextImpl, priority)
|
||||||
|
|
||||||
fun schedule(f: (SuspendContextImpl) -> Unit) {
|
fun invoke(f: (SuspendContextImpl) -> Unit) {
|
||||||
val suspendContextCommand = object : SuspendContextCommandImpl(suspendContext) {
|
debugProcess.managerThread.invoke(makeCommand(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeCommand(f: (SuspendContextImpl) -> Unit) =
|
||||||
|
object : SuspendContextCommandImpl(suspendContext) {
|
||||||
override fun getPriority() = this@ManagerThreadExecutorInstance.priority
|
override fun getPriority() = this@ManagerThreadExecutorInstance.priority
|
||||||
|
|
||||||
override fun contextAction(suspendContext: SuspendContextImpl) {
|
override fun contextAction(suspendContext: SuspendContextImpl) {
|
||||||
f(suspendContext)
|
f(suspendContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugProcess.managerThread.invoke(suspendContextCommand)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ class ApplicationThreadExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun schedule(f: () -> Unit, component: Component) {
|
fun schedule(f: () -> Unit, component: Component) {
|
||||||
return ApplicationManager.getApplication().invokeLater( { f() }, ModalityState.stateForComponent(component))
|
return ApplicationManager.getApplication().invokeLater({ f() }, ModalityState.stateForComponent(component))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun schedule(f: () -> Unit) {
|
fun schedule(f: () -> Unit) {
|
||||||
|
|||||||
+2
-2
@@ -18,10 +18,10 @@ abstract class BaseDynamicMirror<T>(val value: ObjectReference, val name: String
|
|||||||
fun makeField(fieldName: String): Field? =
|
fun makeField(fieldName: String): Field? =
|
||||||
cls?.let { it.fieldByName(fieldName) }
|
cls?.let { it.fieldByName(fieldName) }
|
||||||
|
|
||||||
fun makeMethod(methodName: String): Method? =
|
fun findMethod(methodName: String): Method? =
|
||||||
cls?.let { it.methodsByName(methodName).single() }
|
cls?.let { it.methodsByName(methodName).single() }
|
||||||
|
|
||||||
fun makeMethod(methodName: String, signature: String): Method? =
|
fun findMethod(methodName: String, signature: String): Method? =
|
||||||
cls?.let { it.methodsByName(methodName, signature).single() }
|
cls?.let { it.methodsByName(methodName, signature).single() }
|
||||||
|
|
||||||
fun isCompatible(value: ObjectReference?) =
|
fun isCompatible(value: ObjectReference?) =
|
||||||
|
|||||||
+2
-2
@@ -170,8 +170,8 @@ data class MirrorOfCoroutineInfo(
|
|||||||
class CoroutineStackFrame(value: ObjectReference, context: DefaultExecutionContext) :
|
class CoroutineStackFrame(value: ObjectReference, context: DefaultExecutionContext) :
|
||||||
BaseDynamicMirror<MirrorOfCoroutineStackFrame>(value, "kotlin.coroutines.jvm.internal.CoroutineStackFrame", context) {
|
BaseDynamicMirror<MirrorOfCoroutineStackFrame>(value, "kotlin.coroutines.jvm.internal.CoroutineStackFrame", context) {
|
||||||
private val stackTraceElementMirror = StackTraceElement(context)
|
private val stackTraceElementMirror = StackTraceElement(context)
|
||||||
private val callerFrameMethod = makeMethod("getCallerFrame")
|
private val callerFrameMethod = findMethod("getCallerFrame")
|
||||||
private val getStackTraceElementMethod = makeMethod("getStackTraceElement")
|
private val getStackTraceElementMethod = findMethod("getStackTraceElement")
|
||||||
|
|
||||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfCoroutineStackFrame? {
|
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfCoroutineStackFrame? {
|
||||||
val objectReference = objectValue(value, callerFrameMethod, context)
|
val objectReference = objectValue(value, callerFrameMethod, context)
|
||||||
|
|||||||
+8
-10
@@ -6,10 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror
|
package org.jetbrains.kotlin.idea.debugger.coroutine.proxy.mirror
|
||||||
|
|
||||||
import com.sun.jdi.ArrayReference
|
import com.sun.jdi.ArrayReference
|
||||||
import com.sun.jdi.ClassType
|
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
import com.sun.jdi.StringReference
|
import com.sun.jdi.StringReference
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.isBaseContinuationImpl
|
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
import org.jetbrains.kotlin.idea.debugger.evaluate.DefaultExecutionContext
|
||||||
|
|
||||||
@@ -20,10 +18,8 @@ class DebugMetadata private constructor(context: DefaultExecutionContext) :
|
|||||||
makeMethod("getSpilledVariableFieldMapping", "(Lkotlin/coroutines/jvm/internal/BaseContinuationImpl;)[Ljava/lang/String;")
|
makeMethod("getSpilledVariableFieldMapping", "(Lkotlin/coroutines/jvm/internal/BaseContinuationImpl;)[Ljava/lang/String;")
|
||||||
val baseContinuationImpl = BaseContinuationImpl(context, this)
|
val baseContinuationImpl = BaseContinuationImpl(context, this)
|
||||||
|
|
||||||
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfDebugProbesImpl? {
|
override fun fetchMirror(value: ObjectReference, context: DefaultExecutionContext): MirrorOfDebugProbesImpl? =
|
||||||
// @TODO fix this
|
throw IllegalStateException("Not meant to be mirrored.")
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchContinuationStack(continuation: ObjectReference, context: DefaultExecutionContext): MirrorOfContinuationStack {
|
fun fetchContinuationStack(continuation: ObjectReference, context: DefaultExecutionContext): MirrorOfContinuationStack {
|
||||||
val coroutineStack = mutableListOf<MirrorOfStackFrame>()
|
val coroutineStack = mutableListOf<MirrorOfStackFrame>()
|
||||||
@@ -45,13 +41,14 @@ class DebugMetadata private constructor(context: DefaultExecutionContext) :
|
|||||||
companion object {
|
companion object {
|
||||||
val log by logger
|
val log by logger
|
||||||
|
|
||||||
fun instance(context: DefaultExecutionContext) =
|
fun instance(context: DefaultExecutionContext): DebugMetadata? {
|
||||||
try {
|
try {
|
||||||
DebugMetadata(context)
|
return DebugMetadata(context)
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
log.warn("Attempt to access DebugMetadata", e)
|
log.warn("Attempt to access DebugMetadata", e)
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +84,8 @@ class BaseContinuationImpl(context: DefaultExecutionContext, private val debugMe
|
|||||||
val length = getSpilledVariableFieldMappingReference.length() / 2
|
val length = getSpilledVariableFieldMappingReference.length() / 2
|
||||||
val fieldVariables = ArrayList<FieldVariable>()
|
val fieldVariables = ArrayList<FieldVariable>()
|
||||||
for (index in 0 until length) {
|
for (index in 0 until length) {
|
||||||
fieldVariables.add(getFieldVariableName(getSpilledVariableFieldMappingReference, index) ?: continue)
|
var fieldVariable = getFieldVariableName(getSpilledVariableFieldMappingReference, index) ?: continue
|
||||||
|
fieldVariables.add(fieldVariable)
|
||||||
}
|
}
|
||||||
return fieldVariables
|
return fieldVariables
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-17
@@ -10,13 +10,9 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl
|
|||||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl
|
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl
|
||||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
||||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||||
import com.intellij.util.containers.addIfNotNull
|
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.*
|
import org.jetbrains.kotlin.idea.debugger.coroutine.data.*
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.ContinuationHolder
|
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.ContinuationHolder
|
||||||
import org.jetbrains.kotlin.idea.debugger.safeLineNumber
|
|
||||||
import org.jetbrains.kotlin.idea.debugger.safeLocation
|
|
||||||
import org.jetbrains.kotlin.idea.debugger.safeMethod
|
|
||||||
import java.lang.Integer.min
|
import java.lang.Integer.min
|
||||||
|
|
||||||
|
|
||||||
@@ -42,12 +38,17 @@ class CoroutineFrameBuilder {
|
|||||||
for (runningStackFrameProxy in realFrames) {
|
for (runningStackFrameProxy in realFrames) {
|
||||||
val preflightStackFrame = coroutineExitFrame(runningStackFrameProxy, suspendContext)
|
val preflightStackFrame = coroutineExitFrame(runningStackFrameProxy, suspendContext)
|
||||||
if (preflightStackFrame != null) {
|
if (preflightStackFrame != null) {
|
||||||
coroutineStackFrameList.addIfNotNull(buildRealStackFrameItem(preflightStackFrame.stackFrameProxy))
|
buildRealStackFrameItem(preflightStackFrame.stackFrameProxy)?.let {
|
||||||
|
coroutineStackFrameList.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
val doubleFrameList = build(preflightStackFrame, suspendContext)
|
val doubleFrameList = build(preflightStackFrame, suspendContext)
|
||||||
coroutineStackFrameList.addAll(doubleFrameList.stackTrace)
|
coroutineStackFrameList.addAll(doubleFrameList.stackTrace)
|
||||||
return DoubleFrameList(coroutineStackFrameList, doubleFrameList.creationStackTrace)
|
return DoubleFrameList(coroutineStackFrameList, doubleFrameList.creationStackTrace)
|
||||||
} else {
|
} else {
|
||||||
coroutineStackFrameList.addIfNotNull(buildRealStackFrameItem(runningStackFrameProxy))
|
buildRealStackFrameItem(runningStackFrameProxy)?.let {
|
||||||
|
coroutineStackFrameList.add(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DoubleFrameList(coroutineStackFrameList, emptyList())
|
return DoubleFrameList(coroutineStackFrameList, emptyList())
|
||||||
@@ -62,6 +63,7 @@ class CoroutineFrameBuilder {
|
|||||||
stackFrames.addAll(preflightFrame.restoredStackTrace())
|
stackFrames.addAll(preflightFrame.restoredStackTrace())
|
||||||
|
|
||||||
// rest of the stack
|
// rest of the stack
|
||||||
|
// @TODO perhaps we need to merge the dropped frame below with the last restored (at least variables).
|
||||||
val framesLeft = preflightFrame.threadPreCoroutineFrames.drop(1)
|
val framesLeft = preflightFrame.threadPreCoroutineFrames.drop(1)
|
||||||
stackFrames.addAll(framesLeft.mapIndexedNotNull { index, stackFrameProxyImpl ->
|
stackFrames.addAll(framesLeft.mapIndexedNotNull { index, stackFrameProxyImpl ->
|
||||||
suspendContext.invokeInManagerThread { buildRealStackFrameItem(stackFrameProxyImpl) }
|
suspendContext.invokeInManagerThread { buildRealStackFrameItem(stackFrameProxyImpl) }
|
||||||
@@ -95,17 +97,11 @@ class CoroutineFrameBuilder {
|
|||||||
return suspendContext.invokeInManagerThread {
|
return suspendContext.invokeInManagerThread {
|
||||||
val sem = frame.location().isPreFlight()
|
val sem = frame.location().isPreFlight()
|
||||||
if (sem.isCoroutineFound()) {
|
if (sem.isCoroutineFound()) {
|
||||||
if (coroutineDebuggerTraceEnabled())
|
|
||||||
ContinuationHolder.log.debug("Entry frame found: ${frame.format()}")
|
|
||||||
lookupContinuation(suspendContext, frame, sem)
|
lookupContinuation(suspendContext, frame, sem)
|
||||||
} else
|
} else
|
||||||
null
|
null
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun filterNegativeLineNumberInvokeSuspendFrames(frame: StackFrameProxyImpl): Boolean {
|
}
|
||||||
val method = frame.safeLocation()?.safeMethod() ?: return false
|
|
||||||
return method.isInvokeSuspend() && frame.safeLocation()?.safeLineNumber() ?: 0 < 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lookupContinuation(
|
fun lookupContinuation(
|
||||||
@@ -117,13 +113,14 @@ class CoroutineFrameBuilder {
|
|||||||
return null
|
return null
|
||||||
|
|
||||||
val theFollowingFrames = theFollowingFrames(frame) ?: emptyList()
|
val theFollowingFrames = theFollowingFrames(frame) ?: emptyList()
|
||||||
if (mode.isSuspendMethodParameter()) {
|
val suspendParameterFrame = if (mode.isSuspendMethodParameter()) {
|
||||||
if (theFollowingFrames.isNotEmpty()) {
|
if (theFollowingFrames.isNotEmpty()) {
|
||||||
// have to check next frame if that's invokeSuspend:-1 before proceed, otherwise skip
|
// have to check next frame if that's invokeSuspend:-1 before proceed, otherwise skip
|
||||||
val invokeSuspendFrame = lookForTheFollowingFrame(theFollowingFrames) ?: return null
|
lookForTheFollowingFrame(theFollowingFrames) ?: return null
|
||||||
} else
|
} else
|
||||||
return null
|
return null
|
||||||
}
|
} else
|
||||||
|
null
|
||||||
|
|
||||||
if (threadAndContextSupportsEvaluation(suspendContext, frame)) {
|
if (threadAndContextSupportsEvaluation(suspendContext, frame)) {
|
||||||
val context = suspendContext.executionContext() ?: return null
|
val context = suspendContext.executionContext() ?: return null
|
||||||
@@ -133,7 +130,8 @@ class CoroutineFrameBuilder {
|
|||||||
else -> null
|
else -> null
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
val coroutineInfo = ContinuationHolder(context).extractCoroutineInfoData(continuation) ?: return null
|
val continuationHolder = ContinuationHolder.instance(context) ?: return null
|
||||||
|
val coroutineInfo = continuationHolder.extractCoroutineInfoData(continuation) ?: return null
|
||||||
return preflight(frame, theFollowingFrames, coroutineInfo, mode)
|
return preflight(frame, theFollowingFrames, coroutineInfo, mode)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|||||||
+2
-2
@@ -151,7 +151,7 @@ class XCoroutineView(val project: Project, val session: XDebugSession) :
|
|||||||
inner class CoroutineGroupContainer(val suspendContext: SuspendContextImpl) : XValueContainer() {
|
inner class CoroutineGroupContainer(val suspendContext: SuspendContextImpl) : XValueContainer() {
|
||||||
override fun computeChildren(node: XCompositeNode) {
|
override fun computeChildren(node: XCompositeNode) {
|
||||||
if (suspendContext.suspendPolicy == EventRequest.SUSPEND_ALL) {
|
if (suspendContext.suspendPolicy == EventRequest.SUSPEND_ALL) {
|
||||||
managerThreadExecutor.on(suspendContext).schedule {
|
managerThreadExecutor.on(suspendContext).invoke {
|
||||||
val debugProbesProxy = CoroutineDebugProbesProxy(suspendContext)
|
val debugProbesProxy = CoroutineDebugProbesProxy(suspendContext)
|
||||||
|
|
||||||
val emptyDispatcherName = KotlinDebuggerCoroutinesBundle.message("coroutine.view.dispatcher.empty")
|
val emptyDispatcherName = KotlinDebuggerCoroutinesBundle.message("coroutine.view.dispatcher.empty")
|
||||||
@@ -210,7 +210,7 @@ class XCoroutineView(val project: Project, val session: XDebugSession) :
|
|||||||
) : RendererContainer(renderer.render(infoData)) {
|
) : RendererContainer(renderer.render(infoData)) {
|
||||||
|
|
||||||
override fun computeChildren(node: XCompositeNode) {
|
override fun computeChildren(node: XCompositeNode) {
|
||||||
managerThreadExecutor.on(suspendContext).schedule {
|
managerThreadExecutor.on(suspendContext).invoke {
|
||||||
val children = XValueChildrenList()
|
val children = XValueChildrenList()
|
||||||
val doubleFrameList = CoroutineFrameBuilder.build(infoData, suspendContext)
|
val doubleFrameList = CoroutineFrameBuilder.build(infoData, suspendContext)
|
||||||
doubleFrameList?.stackTrace?.forEach {
|
doubleFrameList?.stackTrace?.forEach {
|
||||||
|
|||||||
-15
@@ -211,21 +211,6 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
|||||||
super.expandAll(tree, runnable, HashSet(), filter, suspendContext)
|
super.expandAll(tree, runnable, HashSet(), filter, suspendContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SuspendContextImpl.runActionInSuspendCommand(action: SuspendContextImpl.() -> Unit) {
|
|
||||||
if (myInProgress) {
|
|
||||||
action()
|
|
||||||
} else {
|
|
||||||
val command = object : SuspendContextCommandImpl(this) {
|
|
||||||
override fun contextAction(suspendContext: SuspendContextImpl) {
|
|
||||||
action(suspendContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to execute the action inside a command if we aren't already inside it.
|
|
||||||
debuggerSession.process.managerThread?.invoke(command) ?: command.contextAction(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun mayThrow(collector: MutableMap<String, Throwable>, expression: String, f: () -> Unit) {
|
private fun mayThrow(collector: MutableMap<String, Throwable>, expression: String, f: () -> Unit) {
|
||||||
try {
|
try {
|
||||||
f()
|
f()
|
||||||
|
|||||||
+28
-23
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.debugger.test
|
|||||||
import com.intellij.debugger.engine.AsyncStackTraceProvider
|
import com.intellij.debugger.engine.AsyncStackTraceProvider
|
||||||
import com.intellij.debugger.engine.JavaStackFrame
|
import com.intellij.debugger.engine.JavaStackFrame
|
||||||
import com.intellij.debugger.engine.SuspendContextImpl
|
import com.intellij.debugger.engine.SuspendContextImpl
|
||||||
import com.intellij.debugger.memory.utils.StackFrameItem
|
|
||||||
import com.intellij.execution.configurations.JavaParameters
|
import com.intellij.execution.configurations.JavaParameters
|
||||||
import com.intellij.execution.process.ProcessOutputTypes
|
import com.intellij.execution.process.ProcessOutputTypes
|
||||||
import com.intellij.jarRepository.JarRepositoryManager
|
import com.intellij.jarRepository.JarRepositoryManager
|
||||||
@@ -25,8 +24,7 @@ import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineAsyncStackTraceProvider
|
import org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineAsyncStackTraceProvider
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.PreflightProvider
|
import org.jetbrains.kotlin.idea.debugger.coroutine.PreflightProvider
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CreationCoroutineStackFrameItem
|
import org.jetbrains.kotlin.idea.debugger.coroutine.data.CreationCoroutineStackFrameItem
|
||||||
import org.jetbrains.kotlin.idea.debugger.coroutine.util.format
|
import org.jetbrains.kotlin.idea.debugger.invokeInSuspendManagerThread
|
||||||
import org.jetbrains.kotlin.idea.debugger.invokeInManagerThread
|
|
||||||
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
|
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
|
||||||
import org.jetbrains.kotlin.idea.debugger.test.util.XDebuggerTestUtil
|
import org.jetbrains.kotlin.idea.debugger.test.util.XDebuggerTestUtil
|
||||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||||
@@ -45,14 +43,7 @@ abstract class KotlinDescriptorTestCaseWithStackFrames() : KotlinDescriptorTestC
|
|||||||
val agentList = mutableListOf<JpsMavenRepositoryLibraryDescriptor>()
|
val agentList = mutableListOf<JpsMavenRepositoryLibraryDescriptor>()
|
||||||
val classPath = mutableListOf<String>()
|
val classPath = mutableListOf<String>()
|
||||||
|
|
||||||
protected fun out(stackFrame: StackFrameItem) {
|
protected fun out(frame: XStackFrame) {
|
||||||
if (stackFrame is CreationCoroutineStackFrameItem && stackFrame.first)
|
|
||||||
out(0, "Creation stack frame")
|
|
||||||
out(INDENT_FRAME, stackFrame.format())
|
|
||||||
outVariables(debugProcess.invokeInManagerThread { stackFrame.createFrame(debugProcess) } ?: return)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun out(frame: JavaStackFrame) {
|
|
||||||
out(INDENT_FRAME, XDebuggerTestUtil.getFramePresentation(frame))
|
out(INDENT_FRAME, XDebuggerTestUtil.getFramePresentation(frame))
|
||||||
outVariables(frame)
|
outVariables(frame)
|
||||||
}
|
}
|
||||||
@@ -92,18 +83,33 @@ abstract class KotlinDescriptorTestCaseWithStackFrames() : KotlinDescriptorTestC
|
|||||||
try {
|
try {
|
||||||
out("Thread stack trace:")
|
out("Thread stack trace:")
|
||||||
val stackFrames: List<XStackFrame> = XDebuggerTestUtil.collectFrames(executionStack)
|
val stackFrames: List<XStackFrame> = XDebuggerTestUtil.collectFrames(executionStack)
|
||||||
for (frame in stackFrames) {
|
val suspendContextImpl = suspendContext as SuspendContextImpl
|
||||||
if (frame is JavaStackFrame) {
|
suspendContextImpl.runActionInSuspendCommand {
|
||||||
out(frame)
|
for (frame in stackFrames) {
|
||||||
val stackFrames = asyncStackTraceProvider?.getAsyncStackTrace(frame, suspendContext as SuspendContextImpl)
|
if (frame is JavaStackFrame) {
|
||||||
if (stackFrames != null) {
|
out(frame)
|
||||||
if (stackFrames is PreflightProvider) {
|
val stackFrames = suspendContext.invokeInSuspendManagerThread(debugProcess) {
|
||||||
val preflightFrame = stackFrames.getPreflight()
|
asyncStackTraceProvider?.getAsyncStackTrace(frame, suspendContextImpl)
|
||||||
out(0, preflightFrame.coroutineInfoData.key.toString())
|
}
|
||||||
|
if (stackFrames != null) {
|
||||||
|
if (stackFrames is PreflightProvider) {
|
||||||
|
val preflightFrame = stackFrames.getPreflight()
|
||||||
|
out(0, preflightFrame.coroutineInfoData.key.toString())
|
||||||
|
}
|
||||||
|
for (frameItem in stackFrames) {
|
||||||
|
if (frameItem is CreationCoroutineStackFrameItem && frameItem.first)
|
||||||
|
out(0, "Creation stack frame")
|
||||||
|
|
||||||
|
val frame: XStackFrame? = suspendContext.invokeInSuspendManagerThread(debugProcess) {
|
||||||
|
frameItem.createFrame(debugProcess)
|
||||||
|
}
|
||||||
|
frame?.let {
|
||||||
|
out(frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return@runActionInSuspendCommand
|
||||||
}
|
}
|
||||||
for (frameItem in stackFrames)
|
|
||||||
out(frameItem)
|
|
||||||
return@doWhenXSessionPausedThenResume
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +124,6 @@ abstract class KotlinDescriptorTestCaseWithStackFrames() : KotlinDescriptorTestC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected fun getAsyncStackTraceProvider(): CoroutineAsyncStackTraceProvider? {
|
protected fun getAsyncStackTraceProvider(): CoroutineAsyncStackTraceProvider? {
|
||||||
val area = Extensions.getArea(null)
|
val area = Extensions.getArea(null)
|
||||||
if (!area.hasExtensionPoint(ASYNC_STACKTRACE_EP_NAME)) {
|
if (!area.hasExtensionPoint(ASYNC_STACKTRACE_EP_NAME)) {
|
||||||
|
|||||||
+16
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.debugger.test
|
|||||||
import com.intellij.debugger.actions.MethodSmartStepTarget
|
import com.intellij.debugger.actions.MethodSmartStepTarget
|
||||||
import com.intellij.debugger.engine.*
|
import com.intellij.debugger.engine.*
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||||
|
import com.intellij.debugger.engine.events.SuspendContextCommandImpl
|
||||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
import com.intellij.debugger.impl.JvmSteppingCommandProvider
|
import com.intellij.debugger.impl.JvmSteppingCommandProvider
|
||||||
import com.intellij.debugger.impl.PositionUtil
|
import com.intellij.debugger.impl.PositionUtil
|
||||||
@@ -157,4 +158,19 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun SuspendContextImpl.runActionInSuspendCommand(action: SuspendContextImpl.() -> Unit) {
|
||||||
|
if (myInProgress) {
|
||||||
|
action()
|
||||||
|
} else {
|
||||||
|
val command = object : SuspendContextCommandImpl(this) {
|
||||||
|
override fun contextAction(suspendContext: SuspendContextImpl) {
|
||||||
|
action(suspendContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to execute the action inside a command if we aren't already inside it.
|
||||||
|
debuggerSession.process.managerThread?.invoke(command) ?: command.contextAction(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -33,8 +33,8 @@ public class XCoroutinesStackTraceTestGenerated extends AbstractXCoroutinesStack
|
|||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("coroutineSuspendFun135.kt")
|
@TestMetadata("coroutineSuspendFun136.kt")
|
||||||
public void testCoroutineSuspendFun135() throws Exception {
|
public void testCoroutineSuspendFun136() throws Exception {
|
||||||
runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun135.kt");
|
runTest("idea/jvm-debugger/jvm-debugger-test/testData/xcoroutines/coroutineSuspendFun136.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ Thread stack trace:
|
|||||||
a:21, SuspendFunKt (coroutine1)
|
a:21, SuspendFunKt (coroutine1)
|
||||||
($completion, $continuation, $result, a, aParam)
|
($completion, $continuation, $result, a, aParam)
|
||||||
CoroutineNameIdState(name=coroutine, id=-1, state=UNKNOWN, dispatcher=null)
|
CoroutineNameIdState(name=coroutine, id=-1, state=UNKNOWN, dispatcher=null)
|
||||||
test1:15, coroutine1.SuspendFunKt
|
test1:15, SuspendFunKt (coroutine1)
|
||||||
(i, test1)
|
(i, test1)
|
||||||
invoke:9, coroutine1.SuspendFunKt$main$result$1
|
invoke:9, SuspendFunKt$main$result$1 (coroutine1)
|
||||||
(continuation, p1, this)
|
(continuation, p1, this)
|
||||||
invokeSuspend:121, kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3
|
invokeSuspend:121, IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3 (kotlin.coroutines.intrinsics)
|
||||||
($i$a$-createCoroutineFromSuspendFunction-IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$2, it, result, this)
|
($i$a$-createCoroutineFromSuspendFunction-IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$2, it, result, this)
|
||||||
resumeWith:33, kotlin.coroutines.jvm.internal.BaseContinuationImpl
|
resumeWith:33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
|
||||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||||
startCoroutine:128, kotlin.coroutines.ContinuationKt
|
startCoroutine:128, ContinuationKt (kotlin.coroutines)
|
||||||
($this$startCoroutine, completion, receiver)
|
($this$startCoroutine, completion, receiver)
|
||||||
main:9, coroutine1.SuspendFunKt
|
main:9, SuspendFunKt (coroutine1)
|
||||||
(cnt)
|
(cnt)
|
||||||
Disconnected from the target VM
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
|||||||
+16
-16
@@ -8,38 +8,38 @@ Thread stack trace:
|
|||||||
b:23, CoroutineSuspendFunKt (continuation)
|
b:23, CoroutineSuspendFunKt (continuation)
|
||||||
($completion, $continuation, $result, b, paramA)
|
($completion, $continuation, $result, b, paramA)
|
||||||
CoroutineNameIdState(name=coroutine, id=1, state=RUNNING, dispatcher=BlockingEventLoop@6f45df59)
|
CoroutineNameIdState(name=coroutine, id=1, state=RUNNING, dispatcher=BlockingEventLoop@6f45df59)
|
||||||
a:16, continuation.CoroutineSuspendFunKt
|
a:16, CoroutineSuspendFunKt (continuation)
|
||||||
(a)
|
(a)
|
||||||
invokeSuspend:10, continuation.CoroutineSuspendFunKt$main$1
|
invokeSuspend:10, CoroutineSuspendFunKt$main$1 (continuation)
|
||||||
($this$runBlocking)
|
($this$runBlocking)
|
||||||
resumeWith:33, kotlin.coroutines.jvm.internal.BaseContinuationImpl
|
resumeWith:33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
|
||||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||||
run:56, kotlinx.coroutines.DispatchedTask
|
run:56, DispatchedTask (kotlinx.coroutines)
|
||||||
($i$a$-withCoroutineContext-DispatchedTask$run$1, $i$f$withCoroutineContext, context, continuation, countOrElement$iv, delegate, exception, fatalException, job, oldValue$iv, state, taskContext, this)
|
($i$a$-withCoroutineContext-DispatchedTask$run$1, $i$f$withCoroutineContext, context, continuation, countOrElement$iv, delegate, exception, fatalException, job, oldValue$iv, state, taskContext, this)
|
||||||
processNextEvent:272, kotlinx.coroutines.EventLoopImplBase
|
processNextEvent:272, EventLoopImplBase (kotlinx.coroutines)
|
||||||
(delayed, this)
|
(delayed, this)
|
||||||
joinBlocking:79, kotlinx.coroutines.BlockingCoroutine
|
joinBlocking:79, BlockingCoroutine (kotlinx.coroutines)
|
||||||
(this)
|
(this)
|
||||||
runBlocking:54, kotlinx.coroutines.BuildersKt__BuildersKt
|
runBlocking:54, BuildersKt__BuildersKt (kotlinx.coroutines)
|
||||||
(block, context, contextInterceptor, coroutine, currentThread, eventLoop, newContext)
|
(block, context, contextInterceptor, coroutine, currentThread, eventLoop, newContext)
|
||||||
runBlocking:1, kotlinx.coroutines.BuildersKt
|
runBlocking:1, BuildersKt (kotlinx.coroutines)
|
||||||
()
|
()
|
||||||
runBlocking$default:36, kotlinx.coroutines.BuildersKt__BuildersKt
|
runBlocking$default:36, BuildersKt__BuildersKt (kotlinx.coroutines)
|
||||||
()
|
()
|
||||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
runBlocking$default:1, BuildersKt (kotlinx.coroutines)
|
||||||
()
|
()
|
||||||
main:9, continuation.CoroutineSuspendFunKt
|
main:9, CoroutineSuspendFunKt (continuation)
|
||||||
(main)
|
(main)
|
||||||
Creation stack frame
|
Creation stack frame
|
||||||
createCoroutineUnintercepted:116, kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt
|
createCoroutineUnintercepted:116, IntrinsicsKt__IntrinsicsJvmKt (kotlin.coroutines.intrinsics)
|
||||||
()
|
()
|
||||||
startCoroutineCancellable:26, kotlinx.coroutines.intrinsics.CancellableKt
|
startCoroutineCancellable:26, CancellableKt (kotlinx.coroutines.intrinsics)
|
||||||
()
|
()
|
||||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
runBlocking$default:1, BuildersKt (kotlinx.coroutines)
|
||||||
()
|
()
|
||||||
main:9, continuation.CoroutineSuspendFunKt
|
main:9, CoroutineSuspendFunKt (continuation)
|
||||||
()
|
()
|
||||||
main:-1, continuation.CoroutineSuspendFunKt
|
main:-1, CoroutineSuspendFunKt (continuation)
|
||||||
()
|
()
|
||||||
Disconnected from the target VM
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
|||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
LineBreakpoint created at coroutineSuspendFun135.kt:29
|
|
||||||
Run Java
|
|
||||||
Connected to the target VM
|
|
||||||
coroutineSuspendFun135.kt:29
|
|
||||||
Thread stack trace:
|
|
||||||
c:29, CoroutineSuspendFun135Kt (continuation)
|
|
||||||
($completion, c, paramB)
|
|
||||||
b:23, CoroutineSuspendFun135Kt (continuation)
|
|
||||||
($completion, $continuation, $result, b, paramA)
|
|
||||||
CoroutineNameIdState(name=coroutine, id=1, state=RUNNING, dispatcher=BlockingEventLoop@305fd85d)
|
|
||||||
a:16, continuation.CoroutineSuspendFun135Kt
|
|
||||||
(a)
|
|
||||||
invokeSuspend:10, continuation.CoroutineSuspendFun135Kt$main$1
|
|
||||||
($this$runBlocking)
|
|
||||||
resumeWith:33, kotlin.coroutines.jvm.internal.BaseContinuationImpl
|
|
||||||
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
|
||||||
run:56, kotlinx.coroutines.DispatchedTask
|
|
||||||
($i$a$-withCoroutineContext-DispatchedTask$run$1, $i$f$withCoroutineContext, context, continuation, countOrElement$iv, delegate, exception, fatalException, job, oldValue$iv, state, taskContext, this)
|
|
||||||
processNextEvent:274, kotlinx.coroutines.EventLoopImplBase
|
|
||||||
(delayed, task, this)
|
|
||||||
joinBlocking:79, kotlinx.coroutines.BlockingCoroutine
|
|
||||||
(this)
|
|
||||||
runBlocking:54, kotlinx.coroutines.BuildersKt__BuildersKt
|
|
||||||
(block, context, contextInterceptor, coroutine, currentThread, eventLoop, newContext)
|
|
||||||
runBlocking:1, kotlinx.coroutines.BuildersKt
|
|
||||||
()
|
|
||||||
runBlocking$default:36, kotlinx.coroutines.BuildersKt__BuildersKt
|
|
||||||
()
|
|
||||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
|
||||||
()
|
|
||||||
main:9, continuation.CoroutineSuspendFun135Kt
|
|
||||||
(main)
|
|
||||||
Creation stack frame
|
|
||||||
createCoroutineUnintercepted:116, kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt
|
|
||||||
()
|
|
||||||
startCoroutineCancellable:26, kotlinx.coroutines.intrinsics.CancellableKt
|
|
||||||
()
|
|
||||||
runBlocking$default:1, kotlinx.coroutines.BuildersKt
|
|
||||||
()
|
|
||||||
main:9, continuation.CoroutineSuspendFun135Kt
|
|
||||||
()
|
|
||||||
main:-1, continuation.CoroutineSuspendFun135Kt
|
|
||||||
()
|
|
||||||
Disconnected from the target VM
|
|
||||||
|
|
||||||
Process finished with exit code 0
|
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
LineBreakpoint created at coroutineSuspendFun136.kt:29
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
coroutineSuspendFun136.kt:29
|
||||||
|
Thread stack trace:
|
||||||
|
c:29, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
($completion, c, paramB)
|
||||||
|
b:23, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
($completion, $continuation, $result, b, paramA)
|
||||||
|
CoroutineNameIdState(name=coroutine, id=1, state=RUNNING, dispatcher=BlockingEventLoop@305fd85d)
|
||||||
|
a:16, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
(a)
|
||||||
|
invokeSuspend:10, CoroutineSuspendFun136Kt$main$1 (continuation)
|
||||||
|
($this$runBlocking)
|
||||||
|
resumeWith:33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
|
||||||
|
($i$a$-with-BaseContinuationImpl$resumeWith$1, $this$with, completion, current, param, result, this)
|
||||||
|
run:56, DispatchedTask (kotlinx.coroutines)
|
||||||
|
($i$a$-withCoroutineContext-DispatchedTask$run$1, $i$f$withCoroutineContext, context, continuation, countOrElement$iv, delegate, exception, fatalException, job, oldValue$iv, state, taskContext, this)
|
||||||
|
processNextEvent:274, EventLoopImplBase (kotlinx.coroutines)
|
||||||
|
(delayed, task, this)
|
||||||
|
joinBlocking:79, BlockingCoroutine (kotlinx.coroutines)
|
||||||
|
(this)
|
||||||
|
runBlocking:54, BuildersKt__BuildersKt (kotlinx.coroutines)
|
||||||
|
(block, context, contextInterceptor, coroutine, currentThread, eventLoop, newContext)
|
||||||
|
runBlocking:1, BuildersKt (kotlinx.coroutines)
|
||||||
|
()
|
||||||
|
runBlocking$default:36, BuildersKt__BuildersKt (kotlinx.coroutines)
|
||||||
|
()
|
||||||
|
runBlocking$default:1, BuildersKt (kotlinx.coroutines)
|
||||||
|
()
|
||||||
|
main:9, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
(main)
|
||||||
|
Creation stack frame
|
||||||
|
createCoroutineUnintercepted:116, IntrinsicsKt__IntrinsicsJvmKt (kotlin.coroutines.intrinsics)
|
||||||
|
()
|
||||||
|
startCoroutineCancellable:26, CancellableKt (kotlinx.coroutines.intrinsics)
|
||||||
|
()
|
||||||
|
runBlocking$default:1, BuildersKt (kotlinx.coroutines)
|
||||||
|
()
|
||||||
|
main:9, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
()
|
||||||
|
main:-1, CoroutineSuspendFun136Kt (continuation)
|
||||||
|
()
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -61,3 +61,4 @@ org.jetbrains.kotlin.idea.debugger.test.AsyncStackTraceTestGenerated.testAsyncLa
|
|||||||
org.jetbrains.kotlin.idea.debugger.test.AsyncStackTraceTestGenerated.testAsyncSimple, redesign test AsyncStackTraces
|
org.jetbrains.kotlin.idea.debugger.test.AsyncStackTraceTestGenerated.testAsyncSimple, redesign test AsyncStackTraces
|
||||||
org.jetbrains.kotlin.idea.debugger.test.KotlinSteppingTestGenerated.StepOver.testStepOverInlinedLambdaStdlib, fails after advancing bootstrap KT-37879
|
org.jetbrains.kotlin.idea.debugger.test.KotlinSteppingTestGenerated.StepOver.testStepOverInlinedLambdaStdlib, fails after advancing bootstrap KT-37879
|
||||||
org.jetbrains.kotlin.incremental.IncrementalJsKlibCompilerRunnerTestGenerated.ClassHierarchyAffected.testMethodRemoved, FO in klib required
|
org.jetbrains.kotlin.incremental.IncrementalJsKlibCompilerRunnerTestGenerated.ClassHierarchyAffected.testMethodRemoved, FO in klib required
|
||||||
|
org.jetbrains.kotlin.idea.debugger.test.XCoroutinesStackTraceTestGenerated.testCoroutineSuspendFun135, running test on SNAPSHOT version
|
||||||
|
|||||||
|
Can't render this file because it contains an unexpected character in line 12 and column 132.
|
Reference in New Issue
Block a user