[debugger] EA-1583106 Explicitly load util class in case of debug attach

Fixes for IDEA-362750

GitOrigin-RevId: 4f6fc7eb45ea2e4beafdebdcf22973cb815c9977
This commit is contained in:
Maksim Zuev
2024-12-06 14:55:00 +00:00
committed by intellij-monorepo-bot
parent 8a6703d5fa
commit a5f063e9cf
3 changed files with 27 additions and 3 deletions
@@ -3,7 +3,7 @@ package com.intellij.rt.debugger.coroutines;
import java.util.List;
final class JsonUtils {
public final class JsonUtils {
private JsonUtils() { }
static String dumpCoroutineStackTraceDumpToJson(
@@ -7,9 +7,12 @@ import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.MethodInvokeUtils
import com.intellij.debugger.engine.SuspendContextImpl
import com.intellij.debugger.engine.SuspendManagerUtil
import com.intellij.debugger.engine.evaluation.EvaluateException
import com.intellij.debugger.impl.ClassLoadingUtils
import com.intellij.debugger.impl.DebuggerUtilsEx
import com.intellij.debugger.impl.DebuggerUtilsImpl
import com.intellij.debugger.jdi.StackFrameProxyImpl
import com.intellij.openapi.diagnostic.fileLogger
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.util.registry.Registry
import com.intellij.rt.debugger.coroutines.CoroutinesDebugHelper
@@ -253,8 +256,12 @@ private class CoroutineStackFrameInterceptor : StackFrameInterceptor {
}
}
internal fun callMethodFromHelper(helperClass: Class<*>, context: DefaultExecutionContext, methodName: String, args: List<Value?>): Value? {
internal fun callMethodFromHelper(
helperClass: Class<*>, context: DefaultExecutionContext, methodName: String, args: List<Value?>,
vararg additionalClassesToLoad: Class<*>
): Value? {
try {
if (!loadClasses(context, *additionalClassesToLoad)) return null
return DebuggerUtilsImpl.invokeHelperMethod(context.evaluationContext, helperClass, methodName, args)
} catch (e: Exception) {
val helperExceptionStackTrace = MethodInvokeUtils.getHelperExceptionStackTrace(context.evaluationContext, e)
@@ -263,3 +270,18 @@ internal fun callMethodFromHelper(helperClass: Class<*>, context: DefaultExecuti
}
return null
}
private fun loadClasses(context: DefaultExecutionContext, vararg additionalClassesToLoad: Class<*>): Boolean {
for (clazz in additionalClassesToLoad) {
try {
if (ClassLoadingUtils.getHelperClass(clazz, context.evaluationContext) == null) {
fileLogger().warn("Cannot load '${clazz.canonicalName}' to the debuggee process")
return false
}
} catch (e: EvaluateException) {
fileLogger().warn("Cannot load '${clazz.canonicalName}' to the debuggee process", e)
return false
}
}
return true
}
@@ -6,6 +6,7 @@ import com.intellij.debugger.engine.JavaValue
import com.intellij.debugger.impl.DebuggerUtilsImpl.logError
import com.intellij.openapi.diagnostic.fileLogger
import com.intellij.rt.debugger.coroutines.CoroutinesDebugHelper
import com.intellij.rt.debugger.coroutines.JsonUtils
import com.sun.jdi.ArrayReference
import com.sun.jdi.ObjectReference
import com.sun.jdi.StringReference
@@ -80,7 +81,8 @@ private fun collectCoroutineAndCreationStack(
continuation: ObjectReference,
context: DefaultExecutionContext
): Pair<List<MirrorOfStackFrame>, List<StackTraceElement>?>? {
val array = callMethodFromHelper(CoroutinesDebugHelper::class.java, context, "getCoroutineStackTraceDump", listOf(continuation))
val array = callMethodFromHelper(CoroutinesDebugHelper::class.java, context, "getCoroutineStackTraceDump", listOf(continuation),
JsonUtils::class.java)
?: return fallbackToOldFetchContinuationStack(continuation, context)
return parseResultFromHelper(array)
}