JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.3k stars 1.18k forks source link

Codeviewer. Crash on Ubuntu #991

Closed igordmn closed 3 years ago

igordmn commented 3 years ago

Ubuntu 20.04.2 LTS, Gnome 3.36.8, X11

  1. Run codeviewer
  2. Click on some tree elements until the app crashes:
Exception in thread "main" java.lang.IllegalStateException: pending composition has not been applied
        at androidx.compose.runtime.CompositionImpl.drainPendingModificationsForCompositionLocked(Composition.kt:443)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:611)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:764)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:103)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:447)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:416)
        at androidx.compose.ui.window.YieldFrameClock.withFrameNanos(Application.desktop.kt:210)
        at androidx.compose.ui.window.YieldFrameClock$withFrameNanos$1.invokeSuspend(Application.desktop.kt)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:708)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

(stacktrace in 1.0.0-alpha1-rc5)

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: pending composition has not been applied
        at androidx.compose.runtime.CompositionImpl.drainPendingModificationsForCompositionLocked(Composition.kt:435)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:578)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:763)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:102)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:446)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:415)
        at androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume(BroadcastFrameClock.kt:42)
        at androidx.compose.runtime.BroadcastFrameClock.sendFrame(BroadcastFrameClock.kt:63)
        at androidx.compose.ui.platform.DesktopOwners.onFrame(DesktopOwners.desktop.kt:120)
        at androidx.compose.desktop.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:122)
        at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.kt:292)
        at org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer.update(LinuxOpenGLRedrawer.kt:52)
        at org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer.access$update(LinuxOpenGLRedrawer.kt:14)
        at org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer$Companion$frameDispatcher$1.invokeSuspend(LinuxOpenGLRedrawer.kt:75)
        at org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer$Companion$frameDispatcher$1.invoke(LinuxOpenGLRedrawer.kt)
        at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(FrameDispatcher.kt:36)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:708)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

(stacktrace in 0.4.0-build208)

0.4.0-build208 + Kotlin 1.5.0 - crash happens 0.4.0-build190 + Kotlin 1.4.32 - crash doesn't happen

igordmn commented 3 years ago

Similar issue in Google tracker:

yaroslavkulinich commented 3 years ago

The same on Windows. No logical steps to reproduce constantly, it just crashes from time to time. I use 1.0.0-alpha3. Would be great to know how to avoid this (even some workaround).

yaroslavkulinich commented 3 years ago

@igordmn Any news with this kind of trouble? Maybe there are some suggestions on when to expect and how to avoid it? Because one of my components crashes in different cases. Some repeatable cases (from time to time) are: navigating back to the previous screen (pop) and using the popup menu. But I still can't understand what part of code in that component leads to the problem. Thank you.

igordmn commented 3 years ago

Any news with this kind of trouble

Unfortunately, no. To fix this issue, we need to make a minimal reliable reproducer, using only compose.runtime (it seems the bug is inside it).

yaroslavkulinich commented 3 years ago

@igordmn After hours of monkey-testing, I discovered that the "pending composition has not been applied" exception, in my case, was related to LazyColumn. After replacing LazyColumn with Column, everything is fine. I tested directly in my app with complex UI hierarchies, so, unfortunately, can't provide a reproducer. Maybe when will have more time, I will simplify the app code to minimal needed elements and make a reproducer.

One more thing. The exception happens on Windows in my case. On Mac everything is fine.

igordmn commented 3 years ago

Should be fixed in 1.0.0-beta6-dev474

igordmn commented 2 years ago

(adding this information for history)

The reproducer:

import androidx.compose.runtime.AbstractApplier
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composition
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MonotonicFrameClock
import androidx.compose.runtime.currentRecomposeScope
import androidx.compose.runtime.rememberCompositionContext
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.withRunningRecomposer
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import java.util.concurrent.Executors.newSingleThreadExecutor
import kotlin.random.Random

fun main() {
    runBlocking(newSingleThreadExecutor().asCoroutineDispatcher() + TestClock) {
        repeat(300) { num ->
            println("test $num")

            withRunningRecomposer {
                val composition = Composition(TestApplier, it)
                composition.setContent {
                    val scope = currentRecomposeScope
                    Test(Random.nextInt())
                    Test(Random.nextInt())
                    LaunchedEffect(Unit) {
                        scope.invalidate()
                    }
                }
                yield()
                yield()
            }
        }
    }
}

@Composable
fun Test(test: Int) {
    val latestContent = rememberUpdatedState(test)
    latestContent.value

    val parent = rememberCompositionContext()
    LaunchedEffect(Unit) {
        val composition1 = Composition(TestApplier, parent)
        composition1.setContent {
            latestContent.value
        }
        val composition2 = Composition(TestApplier, parent)
        composition2.setContent {
            latestContent.value
        }
    }
}

internal object TestApplier: AbstractApplier<Unit>(Unit) {
    override fun insertTopDown(index: Int, instance: Unit) = Unit
    override fun insertBottomUp(index: Int, instance: Unit) = Unit
    override fun remove(index: Int, count: Int) = Unit
    override fun move(from: Int, to: Int, count: Int) = Unit
    override fun onClear() = Unit
}

object TestClock : MonotonicFrameClock {
    override suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R {
        return onFrame(System.nanoTime())
    }
}

Reproduces only on Eclipse OpenJ9, Ubuntu:

openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 15.0.2+7)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.24.0, JRE 15 Linux amd64-64-Bit Compressed References 20210121_172 (JIT enabled, AOT enabled)
OpenJ9   - 345e1b09e
OMR      - 741e94ea8
JCL      - 863b523566 based on jdk-15.0.2+7)

The issue was because identityHashCode on OpenJ9 returns negative values (issue)

zacharee commented 11 months ago

This seems to have come back with the iOS alpha. Could it be a similar issue?

This was recorded on iOS 17.1.2 on an iPhone 15 Pro Max. I believe the Compose version was 1.6.0-dev1296.

androidx.compose.runtime.ComposeRuntimeError: Compose Runtime internal error. Unexpected or incorrect use of the Compose internal runtime API (pending composition has not been applied). Please report to Google or use https://goo.gle/compose-feedback

0  HINT Control +0xd1dec    kfun:kotlin.Throwable#<init>(){} (Throwable.kt:32:21)
1  HINT Control +0xd1d98    kfun:androidx.compose.runtime#composeRuntimeError(kotlin.String){}kotlin.Nothing (Composer.kt:4558:11)
2  HINT Control +0xe3a54    kfun:androidx.compose.runtime.CompositionImpl.drainPendingModificationsForCompositionLocked#internal (Composition.kt:548:17)
3  HINT Control +0xe3e8c    <inlined-out:<anonymous>> (Composition.kt:586:17)
4  HINT Control +0xf0f98    kfun:androidx.compose.runtime.ControlledComposition#composeContent(kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}-trampoline (Composition.kt:112:5)
5  HINT Control +0xe36b0    kfun:androidx.compose.runtime.CompositionContext#composeInitial(androidx.compose.runtime.ControlledComposition;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}-trampoline (CompositionContext.kt:46:23)
6  HINT Control +0x227c10   <inlined-out:<anonymous>> (SubcomposeLayout.kt:721:17)
7  HINT Control +0x6740f0   kfun:androidx.compose.ui.layout.SubcomposeMeasureScope#subcompose(kotlin.Any?;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}kotlin.collections.List<androidx.compose.ui.layout.Measurable>-trampoline (SubcomposeLayout.kt:369:5)
8  HINT Control +0x3453a4   kfun:androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScopeImpl#measure(kotlin.Int;androidx.compose.ui.unit.Constraints){}kotlin.collections.List<androidx.compose.ui.layout.Placeable> (LazyLayoutMeasureScope.kt:121:54)
9  HINT Control +0x6813ec   kfun:androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope#measure(kotlin.Int;androidx.compose.ui.unit.Constraints){}kotlin.collections.List<androidx.compose.ui.layout.Placeable>-trampoline (LazyLayoutMeasureScope.kt:58:5)
10 HINT Control +0x350fa8   kfun:androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridMeasureProvider#getAndMeasure(kotlin.Int;androidx.compose.foundation.lazy.staggeredgrid.SpanRange){}androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridMeasuredItem (LazyStaggeredGridMeasure.kt:1033:39)
11 HINT Control +0x35242c   <inlined-out:<anonymous>> (LazyStaggeredGridMeasure.kt:507:53)
12 HINT Control +0x355e88   kfun:androidx.compose.foundation.lazy.staggeredgrid#measureStaggeredGrid__at__androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope(androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState;kotlin.collections.List<kotlin.Int>;androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemProvider;androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridSlots;androidx.compose.ui.unit.Constraints;kotlin.Boolean;kotlin.Boolean;androidx.compose.ui.unit.IntOffset;kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridMeasureResult (LazyStaggeredGridMeasure.kt:166:20)
13 HINT Control +0x643744   kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline ([K][Suspend]Functions:1:1)
14 HINT Control +0x340204   <inlined-out:<anonymous>> (LazyLayout.kt:87:25)
15 HINT Control +0x643744   kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline ([K][Suspend]Functions:1:1)
16 HINT Control +0x228bc0   kfun:androidx.compose.ui.layout.LayoutNodeSubcompositionsState.object-1.measure#internal (SubcomposeLayout.kt:866:40)
17 HINT Control +0x673194   kfun:androidx.compose.ui.layout.MeasurePolicy#measure__at__androidx.compose.ui.layout.MeasureScope(kotlin.collections.List<androidx.compose.ui.layout.Measurable>;androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.MeasureResult-trampoline (MeasurePolicy.kt:88:5)
18 HINT Control +0x236aa0   <inlined-out:<anonymous>> (InnerNodeCoordinator.kt:126:13)
19 HINT Control +0x66c33c   kfun:androidx.compose.ui.layout.Measurable#measure(androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.Placeable-trampoline (Measurable.kt:30:5)
20 HINT Control +0x2e11a4   kfun:androidx.compose.foundation.layout.OffsetPxNode.measure#internal (Offset.kt:245:36)
21 HINT Control +0x6751a0   kfun:androidx.compose.ui.node.LayoutModifierNode#measure__at__androidx.compose.ui.layout.MeasureScope(androidx.compose.ui.layout.Measurable;androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.MeasureResult-trampoline (LayoutModifierNode.kt:64:5)
22 HINT Control +0x23a280   <inlined-out:<anonymous>> (LayoutModifierNodeCoordinator.kt:116:21)
23 HINT Control +0x66c33c   kfun:androidx.compose.ui.layout.Measurable#measure(androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.Placeable-trampoline (Measurable.kt:30:5)
24 HINT Control +0x202a1c   kfun:androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure#internal (GraphicsLayerModifier.kt:646:36)
25 HINT Control +0x6751a0   kfun:androidx.compose.ui.node.LayoutModifierNode#measure__at__androidx.compose.ui.layout.MeasureScope(androidx.compose.ui.layout.Measurable;androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.MeasureResult-trampoline (LayoutModifierNode.kt:64:5)
26 HINT Control +0x23a280   <inlined-out:<anonymous>> (LayoutModifierNodeCoordinator.kt:116:21)
27 HINT Control +0x24ccfc   kfun:androidx.compose.ui.node.NodeCoordinator#measure(androidx.compose.ui.unit.Constraints){}androidx.compose.ui.layout.Placeable-trampoline (NodeCoordinator.kt:28:18)
28 HINT Control +0x6414e0   kfun:kotlin.Function0#invoke(){}1:0-trampoline ([K][Suspend]Functions:1:1)
29 HINT Control +0x12197c   <inlined-out:enter> (Snapshot.kt:132:20)
30 HINT Control +0x13803c   <inlined-out:<anonymous>> (SnapshotStateObserver.kt:471:26)
31 HINT Control +0x248834   kfun:androidx.compose.ui.node.OwnerSnapshotObserver#observeReads(0:0;kotlin.Function1<0:0,kotlin.Unit>;kotlin.Function0<kotlin.Unit>){0§<androidx.compose.ui.node.OwnerScope>} (OwnerSnapshotObserver.kt:133:18)
32 HINT Control +0x2421f4   kfun:androidx.compose.ui.node.LayoutNode#remeasure(androidx.compose.ui.unit.Constraints?){}kotlin.Boolean (LayoutNode.kt:1140:33)
33 HINT Control +0x242294   kfun:androidx.compose.ui.node.LayoutNode#remeasure$default(androidx.compose.ui.unit.Constraints?;kotlin.Int){}kotlin.Boolean (LayoutNode.kt:1131:14)
34 HINT Control +0x24f7ec   kfun:androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure#internal (MeasureAndLayoutDelegate.kt:323:24)
35 HINT Control +0x24ff30   kfun:androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded#internal (MeasureAndLayoutDelegate.kt:458:31)
36 HINT Control +0x276b14   <inlined-out:<anonymous>> (MeasureAndLayoutDelegate.kt:344:39)
37 HINT Control +0x284338   kfun:androidx.compose.ui.node.RootNodeOwner#measureAndLayout(){} (RootNodeOwner.skiko.kt:179:15)
38 HINT Control +0x27f260   kfun:androidx.compose.ui.scene.BaseComposeScene#measureAndLayout(){}-trampoline (BaseComposeScene.skiko.kt:220:24)
39 HINT Control +0x2a9478   kfun:androidx.compose.ui.scene.ComposeScene#render(androidx.compose.ui.graphics.Canvas;kotlin.Long){}-trampoline (ComposeScene.skiko.kt:155:5)
40 HINT Control +0x2bbf14   kfun:androidx.compose.ui.window.SkikoUIViewDelegate#render(org.jetbrains.skia.Canvas;kotlin.Double){}-trampoline (SkikoUIView.kt:55:5)
41 HINT Control +0x2b2660   kfun:androidx.compose.ui.window.MetalRedrawerCallbacks#render(org.jetbrains.skia.Canvas;kotlin.Double){}-trampoline (MetalRedrawer.kt:161:5)
42 HINT Control +0x2b389c   <inlined-out:<anonymous>> (MetalRedrawer.kt:251:17)
43 HINT Control +0x6414e0   kfun:kotlin.Function0#invoke(){}1:0-trampoline ([K][Suspend]Functions:1:1)
44 HINT Control +0x2b5d40   kfun:androidx.compose.ui.window.DisplayLinkProxy.handleDisplayLinkTick#internal (MetalRedrawer.kt:457:9)
45 QuartzCore +0x2fa10      CA::Display::DisplayLinkItem::dispatch_(CA::SignPost::Interval<(CA::SignPost::CAEventCode)835322056>&)
46 QuartzCore +0x32bf8      CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long)
47 QuartzCore +0x32704      CA::Display::DisplayLink::callback(_CADisplayTimer*, unsigned long long, unsigned long long, unsigned long long, bool, void*)
48 QuartzCore +0xb1918      CA::Display::DisplayLink::dispatch_deferred_display_links(unsigned int)
49 UIKitCore +0xaa488       __UIUpdateSequenceRun
50 UIKitCore +0xa9b78       _schedulerStepScheduledMainSection
51 UIKitCore +0xa9c34       _runloopSourceCallback
52 CoreFoundation +0x37318  ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
53 CoreFoundation +0x36594  ___CFRunLoopDoSource0
54 CoreFoundation +0x34d48  ___CFRunLoopDoSources0
55 CoreFoundation +0x33a84  ___CFRunLoopRun
56 CoreFoundation +0x33664  _CFRunLoopRunSpecific
57 GraphicsServices +0x35e8 _GSEventRunModal
58 UIKitCore +0x22c2b0      -[UIApplication _run]
59 UIKitCore +0x22b8ec      _UIApplicationMain
60 SwiftUI +0x11620f8       0x18cb820f8 (0x18cb8204c + 172)
61 SwiftUI +0x1161f3c       0x18cb81f3c (0x18cb81ea8 + 148)
62 SwiftUI +0xdd3864        0x18c7f3864 (0x18c7f37e8 + 124)
63 HINT Control +0x5948     static iOSApp.$main() (iOSApp.swift)
64 dyld +0x5dc8             start
m-sasha commented 11 months ago

@zacharee Can you post a short snipped where this is reproduced?

zacharee commented 11 months ago

This is from a crash report on Bugsnag, so I don't know exactly how to reproduce it. This is the code, though: https://github.com/zacharee/ArcadyanKVD21Control/blob/727ce98524e71a056098dd9af67d5c278a835bf0/common/src/commonMain/kotlin/dev/zwander/common/components/PageGrid.kt.

m-sasha commented 11 months ago

Unfortunately there's not much we can do without a reproducer here.

okushnikov commented 2 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.