puniverse / quasar

Fibers, Channels and Actors for the JVM

Home Page:http://docs.paralleluniverse.co/quasar/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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)