Incorrect instrumentation verification codepath triggered by function overloads.
exFalso opened this issue · comments
The following code:
import co.paralleluniverse.fibers.Fiber
import co.paralleluniverse.fibers.Suspendable
@Suspendable
fun function() {
function(arrayOf(0))
}
@Suspendable
fun function(m: Any) {
Fiber.yield()
}
fun main(args: Array<String>) {
val fiber = object : Fiber<Any>() {
@Suspendable
override fun run(): Any {
return function(object {})
}
}
fiber.start().get()
}
produces
QUASAR WARNING: Assertions enabled. This may harm performance.
QUASAR WARNING: Fibers are set to verify instrumentation. This may *severely* harm performance.
WARNING: Uninstrumented whole methods ('**') or single calls ('!!') detected:
at co.paralleluniverse.common.util.ExtendedStackTrace.here() (ExtendedStackTrace.java:46)
at co.paralleluniverse.fibers.Fiber.checkInstrumentation() (Fiber.java:1694)
at co.paralleluniverse.fibers.Fiber.verifySuspend(co.paralleluniverse.fibers.Fiber) (Fiber.java:1667)
at co.paralleluniverse.fibers.Fiber.verifySuspend() (Fiber.java:1662)
at co.paralleluniverse.fibers.Fiber.yield() (Fiber.java:665)
at AKt.function() (A.kt:11) !! (instrumented suspendable calls at: lines [6], calls [AKt.function(java.lang.Object)])
at AKt$main$fiber$1.run() (A.kt:19) !! (instrumented suspendable calls at: lines [19], calls [AKt.function(java.lang.Object)])
at co.paralleluniverse.fibers.Fiber.run1() (Fiber.java:1092)
There are two variants of function
, one with no args, and one that accepts an Any
. The one with no args is never actually called, however note that in the stack trace it shows up
at AKt.function() (A.kt:11) !! (instrumented suspendable calls at: lines [6], calls [AKt.function(java.lang.Object)])
.
When this unused function is deleted verification succeeds as it should.
Digging a bit deeper, the overload of function
triggers the more complex code path in ExtendedStackTrace.java:getMethod()
. From what I understand this codepath tries to figure out which variant was called by using line number information in the bytecode. I think the bug is in this code, setting a breakpoint on the visitEnd()
function in the MethodVisitor
reveals minLine = 6, maxLine = 26
, which is the merge of both function's min/max line number. This means the visitor states got mixed up somehow, causing that codepath to pick the wrong method.
With which Quasar version does it happen? I couldn't reproduce it with 0.7.9
and Kotlin 1.1.51
.
I tried it with Quasar 0.7.9
and Kotlin 1.1.51
and it does the same. Note that this requires instrumentation verification on (-Dco.paralleluniverse.fibers.verifyInstrumentation=true
)