Skip to content

Commit 9013717

Browse files
committed
Sanitize class names received from Kotlin debug metadata
1 parent 0ede961 commit 9013717

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

core/kotlinx-coroutines-core/src/internal/Exceptions.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,24 @@ private fun <E : Throwable> recoveryDisabled(exception: E) =
9090

9191
private fun createStackTrace(continuation: CoroutineStackFrame): ArrayList<StackTraceElement> {
9292
val stack = ArrayList<StackTraceElement>()
93-
continuation.getStackTraceElement()?.let { stack.add(it) }
93+
continuation.getStackTraceElement()?.let { stack.add(sanitize(it)) }
9494

9595
var last = continuation
9696
while (true) {
9797
last = (last as? CoroutineStackFrame)?.callerFrame ?: break
98-
last.getStackTraceElement()?.let { stack.add(it) }
98+
last.getStackTraceElement()?.let { stack.add(sanitize(it)) }
9999
}
100100
return stack
101101
}
102102

103+
internal fun sanitize(element: StackTraceElement): StackTraceElement {
104+
if (!element.className.contains('/')) {
105+
return element
106+
}
103107

108+
// STE generated with debug metadata contains '/' as separators in FQN, while Java contains dots
109+
return StackTraceElement(element.className.replace('/', '.'), element.methodName, element.fileName, element.lineNumber)
110+
}
104111
internal fun artificialFrame(message: String) = java.lang.StackTraceElement("\b\b\b($message", "\b", "\b", -1)
105112
internal fun StackTraceElement.isArtificial() = className.startsWith("\b\b\b")
106113

core/kotlinx-coroutines-core/test/exceptions/StackTraceRecoveryTest.kt

+19-19
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ class StackTraceRecoveryTest : TestBase() {
3232
val traces = listOf(
3333
"java.util.concurrent.ExecutionException\n" +
3434
"\t(Current coroutine stacktrace)\n" +
35-
"\tat kotlinx/coroutines/DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
36-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.oneMoreNestedMethod(StackTraceRecoveryTest.kt:49)\n" +
37-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.nestedMethod(StackTraceRecoveryTest.kt:44)\n" +
38-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$testAsync\$1.invokeSuspend(StackTraceRecoveryTest.kt:17)\n",
35+
"\tat kotlinx.coroutines.DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
36+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.oneMoreNestedMethod(StackTraceRecoveryTest.kt:49)\n" +
37+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.nestedMethod(StackTraceRecoveryTest.kt:44)\n" +
38+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testAsync\$1.invokeSuspend(StackTraceRecoveryTest.kt:17)\n",
3939
"Caused by: java.util.concurrent.ExecutionException\n" +
4040
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testAsync\$1\$1\$1.invokeSuspend(StackTraceRecoveryTest.kt:21)\n" +
4141
"\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n"
@@ -54,10 +54,10 @@ class StackTraceRecoveryTest : TestBase() {
5454
val stacktrace = listOf(
5555
"java.util.concurrent.ExecutionException\n" +
5656
"\t(Current coroutine stacktrace)\n" +
57-
"\tat kotlinx/coroutines/DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
58-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.oneMoreNestedMethod(StackTraceRecoveryTest.kt:81)\n" +
59-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.nestedMethod(StackTraceRecoveryTest.kt:75)\n" +
60-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$testCompletedAsync\$1.invokeSuspend(StackTraceRecoveryTest.kt:71)",
57+
"\tat kotlinx.coroutines.DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
58+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.oneMoreNestedMethod(StackTraceRecoveryTest.kt:81)\n" +
59+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.nestedMethod(StackTraceRecoveryTest.kt:75)\n" +
60+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCompletedAsync\$1.invokeSuspend(StackTraceRecoveryTest.kt:71)",
6161
"Caused by: java.util.concurrent.ExecutionException\n" +
6262
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCompletedAsync\$1\$deferred\$1.invokeSuspend(StackTraceRecoveryTest.kt:44)\n" +
6363
"\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)"
@@ -92,8 +92,8 @@ class StackTraceRecoveryTest : TestBase() {
9292
channel, listOf(
9393
"java.lang.IllegalArgumentException\n" +
9494
"\t(Current coroutine stacktrace)\n" +
95-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.channelNestedMethod(StackTraceRecoveryTest.kt:110)\n" +
96-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$testReceiveFromChannel\$1.invokeSuspend(StackTraceRecoveryTest.kt:89)",
95+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.channelNestedMethod(StackTraceRecoveryTest.kt:110)\n" +
96+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromChannel\$1.invokeSuspend(StackTraceRecoveryTest.kt:89)",
9797
"Caused by: java.lang.IllegalArgumentException\n" +
9898
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testReceiveFromChannel\$1\$job\$1.invokeSuspend(StackTraceRecoveryTest.kt:93)\n" +
9999
"\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n" +
@@ -142,11 +142,11 @@ class StackTraceRecoveryTest : TestBase() {
142142
outerMethod(deferred, listOf(
143143
"kotlinx.coroutines.RecoverableTestException\n" +
144144
"\t(Current coroutine stacktrace)\n" +
145-
"\tat kotlinx/coroutines/DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
146-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.innerMethod(StackTraceRecoveryTest.kt:158)\n" +
147-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$outerMethod\$2.invokeSuspend(StackTraceRecoveryTest.kt:151)\n" +
148-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.outerMethod(StackTraceRecoveryTest.kt:150)\n" +
149-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$testWithContext\$1.invokeSuspend(StackTraceRecoveryTest.kt:141)\n",
145+
"\tat kotlinx.coroutines.DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
146+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.innerMethod(StackTraceRecoveryTest.kt:158)\n" +
147+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$outerMethod\$2.invokeSuspend(StackTraceRecoveryTest.kt:151)\n" +
148+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.outerMethod(StackTraceRecoveryTest.kt:150)\n" +
149+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testWithContext\$1.invokeSuspend(StackTraceRecoveryTest.kt:141)\n",
150150
"Caused by: kotlinx.coroutines.RecoverableTestException\n" +
151151
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testWithContext\$1\$deferred\$1.invokeSuspend(StackTraceRecoveryTest.kt:143)\n" +
152152
"\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n"))
@@ -178,10 +178,10 @@ class StackTraceRecoveryTest : TestBase() {
178178
outerScopedMethod(deferred, listOf(
179179
"kotlinx.coroutines.RecoverableTestException\n" +
180180
"\t(Current coroutine stacktrace)\n" +
181-
"\tat kotlinx/coroutines/DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
182-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest.innerMethod(StackTraceRecoveryTest.kt:158)\n" +
183-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$outerScopedMethod\$2.invokeSuspend(StackTraceRecoveryTest.kt:151)\n" +
184-
"\tat kotlinx/coroutines/exceptions/StackTraceRecoveryTest\$testCoroutineScope\$1.invokeSuspend(StackTraceRecoveryTest.kt:141)\n",
181+
"\tat kotlinx.coroutines.DeferredCoroutine.await\$suspendImpl(Builders.common.kt:99)\n" +
182+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest.innerMethod(StackTraceRecoveryTest.kt:158)\n" +
183+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$outerScopedMethod\$2.invokeSuspend(StackTraceRecoveryTest.kt:151)\n" +
184+
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCoroutineScope\$1.invokeSuspend(StackTraceRecoveryTest.kt:141)\n",
185185
"Caused by: kotlinx.coroutines.RecoverableTestException\n" +
186186
"\tat kotlinx.coroutines.exceptions.StackTraceRecoveryTest\$testCoroutineScope\$1\$deferred\$1.invokeSuspend(StackTraceRecoveryTest.kt:143)\n" +
187187
"\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n"))

0 commit comments

Comments
 (0)