Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling coverage breaks synchronized blocks #16940

Closed
mohe2015 opened this issue Feb 16, 2023 · 2 comments
Closed

Enabling coverage breaks synchronized blocks #16940

mohe2015 opened this issue Feb 16, 2023 · 2 comments
Assignees
Labels
area:coverage Code coverage, see https://dotty.epfl.ch/docs/internals/coverage.html itype:bug

Comments

@mohe2015
Copy link

Compiler version

3.2.2

Minimized code

https://github.com/mohe2015/coverage-synchronized-bug

scala -coverage-out coverage src/main/scala/Main.scala

import concurrent.ExecutionContext.Implicits.global
import scala.concurrent.*
import scala.concurrent.duration.*

var test = 0

def brokenSynchronizedBlock(option: Boolean): Future[Unit] = Future {
  if (option) {
    Thread.sleep(500)
  }
  synchronized {
    val tmp = test
    Thread.sleep(1000)
    test = tmp + 1
  }
}

@main def main: Unit = {
  Await.result(Future.sequence(Seq(brokenSynchronizedBlock(false), brokenSynchronizedBlock(true))).map(result => {
    println(test)
    assert(test == 2)
  }), 3.seconds)
}

Output

1
java.util.concurrent.ExecutionException: Boxed Exception
        at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolve(Promise.scala:99)
        at scala.concurrent.impl.Promise$Transformation.handleFailure(Promise.scala:444)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:506)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: java.lang.AssertionError: assertion failed
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:11)
        at Main$package$.$anonfun$1(Main.scala:21)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
        ... 6 more

Expectation

2
@mohe2015 mohe2015 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 16, 2023
@KacperFKorban KacperFKorban added area:coverage Code coverage, see https://dotty.epfl.ch/docs/internals/coverage.html and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 17, 2023
KacperFKorban referenced this issue in dotty-staging/dotty Feb 17, 2023
@KacperFKorban KacperFKorban self-assigned this Feb 17, 2023
KacperFKorban referenced this issue in dotty-staging/dotty Feb 17, 2023
@Martomate
Copy link

I have a similar problem. I get an IllegalMonitorStateException when running this code with sbt coverage test.

val lockedFiles: mutable.Set[String] = mutable.Set.empty
val path = "file.txt"

def submit() =
  lockedFiles.synchronized {
    while lockedFiles.contains(path) do lockedFiles.wait()
    lockedFiles += path
  }
  // do stuff

Looking at the bytecode it seems to represent something more like this:

val lockedFiles: mutable.Set[String] = mutable.Set.empty
val path = "file.txt"

def submit() =
  while lockedFiles.contains(path) do lockedFiles.wait()
  lockedFiles += path

  lockedFiles.synchronized {}
  // do stuff

The synchronized block has been moved to the end!

I use Scala 3.3.0, but have checked that it's also broken on 3.3.1-RC4.

KacperFKorban referenced this issue in dotty-staging/dotty Aug 18, 2023
@KacperFKorban
Copy link
Member

fixed in #16941

Kordyjan referenced this issue Dec 1, 2023
possible fix for lampepfl#16940

[Cherry-picked 17684c5]
Kordyjan referenced this issue Dec 7, 2023
possible fix for lampepfl#16940

[Cherry-picked 17684c5]
Kordyjan referenced this issue Dec 7, 2023
possible fix for lampepfl#16940

[Cherry-picked 17684c5]
Kordyjan referenced this issue Dec 7, 2023
possible fix for lampepfl#16940

[Cherry-picked 17684c5]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:coverage Code coverage, see https://dotty.epfl.ch/docs/internals/coverage.html itype:bug
Projects
None yet
Development

No branches or pull requests

3 participants