Better stack frame cleanup

This commit is contained in:
Robinson 2021-04-27 10:25:19 +02:00
parent f3637219c3
commit ea857da883
1 changed files with 30 additions and 7 deletions

View File

@ -16,7 +16,6 @@
package dorkbox.network.connection
import dorkbox.network.ipFilter.IpFilterRule
import dorkbox.network.ipFilter.IpSubnetFilterRule
import dorkbox.os.OS
import dorkbox.util.classes.ClassHelper
import dorkbox.util.classes.ClassHierarchy
@ -25,6 +24,7 @@ import kotlinx.atomicfu.atomic
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.jodah.typetools.TypeResolver
import java.io.IOException
/**
* Manages all of the different connect/disconnect/etc listeners
@ -47,7 +47,7 @@ internal class ListenerManager<CONNECTION: Connection> {
}
/**
* Remove from the stacktrace (going in reverse), kotlin coroutine info + dorkbox network call stack.
* Remove from the stacktrace kotlin coroutine info + dorkbox network call stack.
*
* Neither of these are useful in resolving exception handling from a users perspective, and only clutter the stacktrace.
*/
@ -56,13 +56,29 @@ internal class ListenerManager<CONNECTION: Connection> {
val stackTrace = throwable.stackTrace
var newEndIndex = stackTrace.size -1 // offset by 1 because we have to adjust for the access index
// maybe offset by 1 because we have to adjust coroutine calls
val firstStartIndex = if (stackTrace[0].methodName == "invokeSuspend") 1 else 0
var newStartIndex = firstStartIndex
for (i in newEndIndex downTo 0) {
val stackName = stackTrace[i].className
if (i == newEndIndex) {
if (stackName.startsWith("kotlinx.coroutines.") ||
stackName.startsWith("kotlin.coroutines.") ||
stackName.startsWith("dorkbox.network.")) {
newEndIndex--
} else {
break
}
}
if (newEndIndex > 0) {
for (i in newStartIndex..newEndIndex) {
val stackName = stackTrace[i].className
if (stackName.startsWith("kotlinx.coroutines.") ||
stackName.startsWith("kotlin.coroutines.") ||
stackName.startsWith("dorkbox.network.")) {
newEndIndex--
stackName.startsWith("kotlin.coroutines.")
) {
newStartIndex++
} else {
break
}
@ -73,7 +89,14 @@ internal class ListenerManager<CONNECTION: Connection> {
if (newEndIndex > 0) {
// newEndIndex will also remove the VERY LAST CachedMethod or CachedAsmMethod access invocation (because it's offset by 1)
throwable.stackTrace = stackTrace.copyOfRange(0, newEndIndex)
if (firstStartIndex == 1) {
// we want to save the FIRST stack frame also
throwable.stackTrace = stackTrace.copyOfRange(0, 1) + stackTrace.copyOfRange(newStartIndex, newEndIndex)
} else {
throwable.stackTrace = stackTrace.copyOfRange(newStartIndex, newEndIndex)
}
} else {
// keep just one, since it's a stack frame INSIDE our network library, and we need that!
throwable.stackTrace = stackTrace.copyOfRange(0, 1)