Hitting breakpoint in Kotlin sometimes doesn't work (KT-22205)
Fix KT-22205 and https://issuetracker.google.com/issues/71556313 Hitting breakpoints in Kotlin JUnit test with an Android Gradle project sometimes(*) does not work in Android Studio 3.1 beta. (*) The issue is related to various threads running concurrently with "dumb" mode background code, so the issue reproduces only on certain configurations. In a nutshell, the issue is as follows * On one hand, gradle build finishes, fires an event ("buildFinished") that is processed "later" and that causes the IDE to enter "dumb" mode for a shot amount of time (about 300-500 msec on a somewhat up to date multi-core computer). * On the other hand, once the JVM of the debuggee is started, breakpoints need to be resolved (on the debugger thread, through a call to com.intellij.debugger.engine.CompoundPositionManager.createPrepareRequests. This code calls into the "KotlinPositionManager.createPrepareRequests", which in turns calls into "PerFileAnalysisCache.analyze". That method returns "AnalysisResult.EMPTY" is the project is in dumb mode. This return value prevents callers from successfully resolving the source location into a breakpoint. Given that the 2 code paths above execute on separate threads without explicit synchronization, the "failed to resolve breakpoint" issue occurs sporadically, to the point it happens 100% of the time on certain configuration. The fix is so wrap the kotlin breakpoint resolution code inside a "runReadActionInSmartMode" so that the debugger thread "waits" for "dumb" mode to terminates before trying to resolve breakpoint locations. #KT-22205 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
b1bcadd762
commit
94ee78c0ca
@@ -26,7 +26,9 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiFile
|
||||
@@ -342,13 +344,15 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
throw NoDataException.INSTANCE
|
||||
}
|
||||
|
||||
val classNames = DebuggerClassNameProvider(myDebugProcess).getOuterClassNamesForPosition(position)
|
||||
return classNames.flatMap { name ->
|
||||
listOfNotNull(
|
||||
myDebugProcess.requestsManager.createClassPrepareRequest(requestor, name),
|
||||
myDebugProcess.requestsManager.createClassPrepareRequest(requestor, "$name$*")
|
||||
)
|
||||
}
|
||||
return DumbService.getInstance(myDebugProcess.project).runReadActionInSmartMode(Computable {
|
||||
val classNames = DebuggerClassNameProvider(myDebugProcess).getOuterClassNamesForPosition(position)
|
||||
classNames.flatMap { name ->
|
||||
listOfNotNull(
|
||||
myDebugProcess.requestsManager.createClassPrepareRequest(requestor, name),
|
||||
myDebugProcess.requestsManager.createClassPrepareRequest(requestor, "$name$*")
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun ReferenceType.containsKotlinStrata() = availableStrata().contains(KOTLIN_STRATA_NAME)
|
||||
|
||||
Reference in New Issue
Block a user