@@ -11,6 +11,21 @@ import java.util.*
1111import kotlin.coroutines.*
1212import kotlin.coroutines.intrinsics.*
1313
14+ /*
15+ * `Class.forName(name).canonicalName` instead of plain `name` is required to properly handle
16+ * Android's minifier that renames these classes and breaks our recovery heuristic without such lookup.
17+ */
18+ private const val baseContinuationImplClass = " kotlin.coroutines.jvm.internal.BaseContinuationImpl"
19+ private const val stackTraceRecoveryClass = " kotlinx.coroutines.internal.StackTraceRecoveryKt"
20+
21+ private val baseContinuationImplClassName = runCatching {
22+ Class .forName(baseContinuationImplClass).canonicalName
23+ }.getOrElse { baseContinuationImplClass }
24+
25+ private val stackTraceRecoveryClassName = runCatching {
26+ Class .forName(stackTraceRecoveryClass).canonicalName
27+ }.getOrElse { stackTraceRecoveryClass }
28+
1429internal actual fun <E : Throwable > recoverStackTrace (exception : E ): E {
1530 if (recoveryDisabled(exception)) return exception
1631 // No unwrapping on continuation-less path: exception is not reported multiple times via slow paths
@@ -21,10 +36,9 @@ internal actual fun <E : Throwable> recoverStackTrace(exception: E): E {
2136private fun <E : Throwable > E.sanitizeStackTrace (): E {
2237 val stackTrace = stackTrace
2338 val size = stackTrace.size
24-
25- val lastIntrinsic = stackTrace.frameIndex(" kotlinx.coroutines.internal.StackTraceRecoveryKt" )
39+ val lastIntrinsic = stackTrace.frameIndex(stackTraceRecoveryClassName)
2640 val startIndex = lastIntrinsic + 1
27- val endIndex = stackTrace.frameIndex(" kotlin.coroutines.jvm.internal.BaseContinuationImpl " )
41+ val endIndex = stackTrace.frameIndex(baseContinuationImplClassName )
2842 val adjustment = if (endIndex == - 1 ) 0 else size - endIndex
2943 val trace = Array (size - lastIntrinsic - adjustment) {
3044 if (it == 0 ) {
@@ -83,7 +97,7 @@ private fun <E : Throwable> recoverFromStackFrame(exception: E, continuation: Co
8397private fun <E : Throwable > createFinalException (cause : E , result : E , resultStackTrace : ArrayDeque <StackTraceElement >): E {
8498 resultStackTrace.addFirst(artificialFrame(" Coroutine boundary" ))
8599 val causeTrace = cause.stackTrace
86- val size = causeTrace.frameIndex(" kotlin.coroutines.jvm.internal.BaseContinuationImpl " )
100+ val size = causeTrace.frameIndex(baseContinuationImplClassName )
87101 if (size == - 1 ) {
88102 result.stackTrace = resultStackTrace.toTypedArray()
89103 return result
0 commit comments