From 4a90e9d0abd93aa8263cf90f8e01d42c63025fd6 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 22 Apr 2019 22:10:32 +0300 Subject: [PATCH] Debugger: Handle exceptions in async stack trace handler more gracefully (EA-141924) --- .../KotlinCoroutinesAsyncStackTraceProvider.kt | 18 ++++++++++++++++-- .../debugger/AbstractAsyncStackTraceTest.kt | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/idea/jvm-debugger/jvm-debugger-core/src/org/jetbrains/kotlin/idea/debugger/KotlinCoroutinesAsyncStackTraceProvider.kt b/idea/jvm-debugger/jvm-debugger-core/src/org/jetbrains/kotlin/idea/debugger/KotlinCoroutinesAsyncStackTraceProvider.kt index 5a39ee53c17..d820d73c351 100644 --- a/idea/jvm-debugger/jvm-debugger-core/src/org/jetbrains/kotlin/idea/debugger/KotlinCoroutinesAsyncStackTraceProvider.kt +++ b/idea/jvm-debugger/jvm-debugger-core/src/org/jetbrains/kotlin/idea/debugger/KotlinCoroutinesAsyncStackTraceProvider.kt @@ -15,6 +15,7 @@ import com.intellij.debugger.jdi.GeneratedLocation import com.intellij.debugger.jdi.StackFrameProxyImpl import com.intellij.debugger.memory.utils.StackFrameItem import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl +import com.intellij.openapi.diagnostic.Logger import com.intellij.xdebugger.frame.XNamedValue import com.sun.jdi.* import org.jetbrains.kotlin.codegen.coroutines.CONTINUATION_VARIABLE_NAME @@ -24,6 +25,8 @@ class KotlinCoroutinesAsyncStackTraceProvider : KotlinCoroutinesAsyncStackTraceP private companion object { const val DEBUG_METADATA_KT = "kotlin.coroutines.jvm.internal.DebugMetadataKt" + private val LOG = Logger.getInstance(this::class.java) + tailrec fun findBaseContinuationSuperSupertype(type: ClassType): ClassType? { if (type.name() == "kotlin.coroutines.jvm.internal.BaseContinuationImpl") { return type @@ -34,10 +37,21 @@ class KotlinCoroutinesAsyncStackTraceProvider : KotlinCoroutinesAsyncStackTraceP } override fun getAsyncStackTrace(stackFrame: JavaStackFrame, suspendContext: SuspendContextImpl): List? { - return getAsyncStackTrace(stackFrame.stackFrameProxy, suspendContext) + return try { + getAsyncStackTraceSafe(stackFrame.stackFrameProxy, suspendContext) + } catch (e: ObjectCollectedException) { + null + } catch (e: IncompatibleThreadStateException) { + null + } catch (e: VMDisconnectedException) { + null + } catch (e: EvaluateException) { + LOG.debug("Cannot evaluate async stack trace", e) + null + } } - fun getAsyncStackTrace(frameProxy: StackFrameProxyImpl, suspendContext: SuspendContextImpl): List? { + fun getAsyncStackTraceSafe(frameProxy: StackFrameProxyImpl, suspendContext: SuspendContextImpl): List? { val location = frameProxy.location() if (!location.isInKotlinSources()) { return null diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractAsyncStackTraceTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractAsyncStackTraceTest.kt index 73c2eba55a3..39befeccc8c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractAsyncStackTraceTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractAsyncStackTraceTest.kt @@ -62,7 +62,7 @@ abstract class AbstractAsyncStackTraceTest : KotlinDebuggerTestBase() { val frameProxy = this.frameProxy if (frameProxy != null) { try { - val stackTrace = asyncStackTraceProvider.getAsyncStackTrace(frameProxy, this) + val stackTrace = asyncStackTraceProvider.getAsyncStackTraceSafe(frameProxy, this) if (stackTrace != null && stackTrace.isNotEmpty()) { print(renderAsyncStackTrace(stackTrace), ProcessOutputTypes.SYSTEM) } else {