Fixed issues cleaning stack traces for proxy invocations

This commit is contained in:
nathan 2020-08-27 00:44:43 +02:00
parent 1750e0a2b0
commit fc28153ed4

View File

@ -492,35 +492,46 @@ object RmiUtils {
val myClassName = RmiClient::class.java.name val myClassName = RmiClient::class.java.name
val stackTrace = localException.stackTrace val stackTrace = localException.stackTrace
var newStartIndex = 0 var newStartIndex = 0
var newEndIndex = stackTrace.size-1 var newEndIndex = stackTrace.size
var foundStart = false
for ((index, element) in stackTrace.withIndex()) {
// step 1: Find the start of our method invocation // step 1: Find the start of our method invocation
for (element in stackTrace) { if (!foundStart) {
newStartIndex++ // "startsWith" because with continuations, the ACTUAL class name is mangled, ie: dorkbox.network.rmi.RmiClient$invoke$$inlined$Continuation$1
if (element.className.startsWith(myClassName)) {
newStartIndex = index
if (element.className == myClassName && element.methodName == "invoke") { // check 1 more time, because we want to remove the proxy invocation off the stack as well.
// we do this 1 more time, because we want to remove the proxy invocation off the stack as well. if (stackTrace[index+1].className.startsWith("com.sun.proxy.")) {
newStartIndex++ newStartIndex++
break
}
} }
// step 2: now we have to find the END index, since a proxy invocation ALWAYS happens starting from our network stack // this is where we will START (not where we are)
for (i in stackTrace.size-1 downTo 0) { newStartIndex++
newEndIndex--
val stackClassName = stackTrace[i].className newEndIndex = newStartIndex
if (stackClassName.startsWith("dorkbox.network.rmi.")) { foundStart = true
}
} else {
// step 2: Find the start of coroutines
val className = element.className
if (className.startsWith("kotlin.coroutines.") || className.startsWith("kotlinx.coroutines.")) {
// -1 because we want to end BEFORE the coroutine suspend call starts
newEndIndex = index-1
break break
} }
} }
}
if (remoteException == null) { if (remoteException == null) {
// no remote exception, just cleanup our own callstack // no remote exception, just cleanup our own callstack
localException.stackTrace = stackTrace.copyOfRange(newStartIndex, newEndIndex) localException.stackTrace = stackTrace.copyOfRange(newStartIndex, newEndIndex)
} else { } else {
// merge this info into the remote exception, so we can get the correct call stack info // merge this info into the remote exception, so we can get the correct call stack info
val newStack = Array<StackTraceElement>(remoteException.stackTrace.size + newEndIndex - newStartIndex) { stackTrace[0] } val newStack = Array<StackTraceElement>(remoteException.stackTrace.size + (newEndIndex - newStartIndex)) { stackTrace[0] }
remoteException.stackTrace.copyInto(newStack) remoteException.stackTrace.copyInto(newStack)
stackTrace.copyInto(newStack, remoteException.stackTrace.size, newStartIndex, newEndIndex) stackTrace.copyInto(newStack, remoteException.stackTrace.size, newStartIndex, newEndIndex)