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

Parallel backend can deadlock when accessing the synchronizing access to frontend. #19293

Closed
WojciechMazur opened this issue Dec 18, 2023 · 0 comments · Fixed by #19298
Closed

Comments

@WojciechMazur
Copy link
Contributor

WojciechMazur commented Dec 18, 2023

When fixed the PR disabled parallel backend tests should be reverted: #19292

Compiler version

Scala 3.4.0-RC1.nightly
Can exist in all 3.4.x versions after merge of #15392

Minimized code

Not yet minimized,
Threads seem to deadlock when accessing the lazy variable which is initialized in the synchronized scope

https://github.com/lampepfl/dotty/blob/e4985fc7d9de349fe3b43ddb06c8369d795c847d/compiler/src/dotty/tools/backend/jvm/CoreBTypes.scala#L170-L178

Where frontendSynch is defined as
https://github.com/lampepfl/dotty/blob/e4985fc7d9de349fe3b43ddb06c8369d795c847d/compiler/src/dotty/tools/backend/jvm/PostProcessorFrontendAccess.scala#L27-L28

Thread 1 dump:

"ForkJoinPool-1-worker-2" #22 daemon prio=5 os_prio=31 cpu=4170.43ms elapsed=1210.47s tid=0x00000001370f8200 nid=0x9f03 waiting on condition  [0x0000000173d5d000]
   java.lang.Thread.State: WAITING (parking)
        at jdk.internal.misc.Unsafe.park(java.base@17.0.7/Native Method)
        - parking to wait for  <0x0000000608a64ff8> (a java.util.concurrent.CountDownLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(java.base@17.0.7/LockSupport.java:211)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@17.0.7/AbstractQueuedSynchronizer.java:715)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base@17.0.7/AbstractQueuedSynchronizer.java:1047)
        at java.util.concurrent.CountDownLatch.await(java.base@17.0.7/CountDownLatch.java:230)
        at dotty.tools.backend.jvm.CoreBTypesFromSymbols.jliLambdaMetaFactoryAltMetafactoryHandle$lzyINIT1(CoreBTypes.scala:178)
        at dotty.tools.backend.jvm.CoreBTypesFromSymbols.jliLambdaMetaFactoryAltMetafactoryHandle(CoreBTypes.scala:170)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genInvokeDynamicLambda(BCodeBodyBuilder.scala:1823)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:383)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:456)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:304)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.loop$1(BCodeBodyBuilder.scala:1210)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadArguments(BCodeBodyBuilder.scala:1217)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genApply(BCodeBodyBuilder.scala:836)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:386)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:304)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genStat(BCodeBodyBuilder.scala:116)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genBlockTo$$anonfun$1(BCodeBodyBuilder.scala:1094)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder$$Lambda$2749/0x00000008007a1b98.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genBlockTo(BCodeBodyBuilder.scala:1094)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:458)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.emitNormalMethodBody$1(BCodeSkelBuilder.scala:893)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genDefDef(BCodeSkelBuilder.scala:916)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:693)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen$$anonfun$1(BCodeSkelBuilder.scala:699)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder$$Lambda$2735/0x0000000800799380.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:699)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:293)
        at dotty.tools.backend.jvm.CodeGen.genClass(CodeGen.scala:155)
        at dotty.tools.backend.jvm.CodeGen.genClassDef$1(CodeGen.scala:63)
        at dotty.tools.backend.jvm.CodeGen.genClassDefs$1(CodeGen.scala:118)
        - locked <0x0000000608f67650> (a java.lang.Object)
        at dotty.tools.backend.jvm.CodeGen.genClassDefs$1$$anonfun$1(CodeGen.scala:116)
        at dotty.tools.backend.jvm.CodeGen$$Lambda$2699/0x00000008007827d8.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.backend.jvm.CodeGen.genClassDefs$1(CodeGen.scala:116)
        at dotty.tools.backend.jvm.CodeGen.genUnit(CodeGen.scala:121)
        at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:83)

Thread 2:

"dotc-genBCode-non-ast-1" #37 daemon prio=5 os_prio=31 cpu=43.99ms elapsed=1205.38s tid=0x000000013c3c2000 nid=0xad0b waiting for monitor entry  [0x00000001755f1000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at dotty.tools.backend.jvm.CoreBTypesFromSymbols.jliLambdaMetaFactoryAltMetafactoryHandle$lzyINIT1(CoreBTypes.scala:170)
        - waiting to lock <0x0000000608f67650> (a java.lang.Object)
        at dotty.tools.backend.jvm.CoreBTypesFromSymbols.jliLambdaMetaFactoryAltMetafactoryHandle(CoreBTypes.scala:170)
        at dotty.tools.backend.jvm.BackendUtils.collectSerializableLambdas$$anonfun$1(BackendUtils.scala:58)
        at dotty.tools.backend.jvm.BackendUtils$$Lambda$2821/0x00000008007c8970.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:933)
        at dotty.tools.backend.jvm.BackendUtils.collectSerializableLambdas(BackendUtils.scala:68)
        at dotty.tools.backend.jvm.PostProcessor.setSerializableLambdas(PostProcessor.scala:88)
        at dotty.tools.backend.jvm.PostProcessor.sendToDisk(PostProcessor.scala:35)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit$$anonfun$1$$anonfun$1$$anonfun$1(GeneratedClassHandler.scala:95)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler$$Lambda$2820/0x00000008007c5710.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.immutable.List.foreach(List.scala:333)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit$$anonfun$1$$anonfun$1(GeneratedClassHandler.scala:95)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit$$anonfun$1$$anonfun$adapted$1(GeneratedClassHandler.scala:97)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler$$Lambda$2819/0x00000008007c5228.apply(Unknown Source)
        at dotty.tools.backend.jvm.PostProcessorFrontendAccess$Impl.withThreadLocalReporter(PostProcessorFrontendAccess.scala:116)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit$$anonfun$1(GeneratedClassHandler.scala:97)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit$$anonfun$adapted$1(GeneratedClassHandler.scala:97)
        at dotty.tools.backend.jvm.GeneratedClassHandler$WritingClassHandler$$Lambda$2817/0x00000008007c3cb0.apply(Unknown Source)

Output


Expectation


@WojciechMazur WojciechMazur self-assigned this Dec 18, 2023
WojciechMazur added a commit that referenced this issue Dec 20, 2023
…9298)

Replaces #19297 and fixes #19293 

The deadlocks are now fixed by introduction of
`PostProcessorFrontendAccess.Lazy[T]` container for which initialization
is synchronized with the frontend Context, while providing a thread-safe
access lacking in original solution.

It now also audits where the unrestricted access to context was used and
replaces these usages with safer access.
Reverts #19292
odersky pushed a commit to dotty-staging/dotty that referenced this issue Jan 6, 2024
…ala#19298)

Replaces scala#19297 and fixes scala#19293 

The deadlocks are now fixed by introduction of
`PostProcessorFrontendAccess.Lazy[T]` container for which initialization
is synchronized with the frontend Context, while providing a thread-safe
access lacking in original solution.

It now also audits where the unrestricted access to context was used and
replaces these usages with safer access.
Reverts scala#19292
WojciechMazur added a commit that referenced this issue Jul 10, 2024
…9298)

Replaces #19297 and fixes #19293 

The deadlocks are now fixed by introduction of
`PostProcessorFrontendAccess.Lazy[T]` container for which initialization
is synchronized with the frontend Context, while providing a thread-safe
access lacking in original solution.

It now also audits where the unrestricted access to context was used and
replaces these usages with safer access.
Reverts #19292
[Cherry-picked 33bdaac][modified]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant