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
15.86k stars 1.15k forks source link

SVG Crash on iOS: org_jetbrains_skia_svg_SVGDOM__1nMakeFromData #4676

Open Andrew0000 opened 4 months ago

Andrew0000 commented 4 months ago

Describe the bug I tried Coil 3 and Kamel for displaying an svg, both crash with org_jetbrains_skia_svg_SVGDOM__1nMakeFromData in traces. It happens on IPhone 11 with iOS 17.4.1. At the same time Svg displays correctly on the simulator.

Kamel:

                      0xf5d4a4 doContent + 4790436
2                        0xf5b340 contentProcessor + 4781888
3                        0xf5a174 doProlog + 4777332
4                        0xf577e8 prologInitProcessor + 4766696
5                        0xf575e0 XML_ParseBuffer + 4766176
6                        0xdc1b30 SkXMLParser::parse(SkStream&) + 3104560
7                        0xdc1328 SkDOM::build(SkStream&) + 3102504
8                        0xfd0224 SkSVGDOM::Builder::make(SkStream&) const + 5260836
9                        0xfc445c SkSVGDOM::MakeFromStream(SkStream&) + 5212252
10                       0xfc4384 org_jetbrains_skia_svg_SVGDOM__1nMakeFromData + 5212036
11                       0x6770a4 kfun:org.jetbrains.skia.svg.SVGDOM#<init>(org.jetbrains.skia.Data){} + 12 (SVGDOM.kt:12)
12                       0x97ff50 kfun:io.kamel.image.decoder.SvgDecoder.$decodeCOROUTINE$0.invokeSuspend#internal + 41 (loadSvgPainter.kt:41)
13                       0x980518 kfun:io.kamel.image.decoder.SvgDecoder#decode#suspend(io.ktor.utils.io.ByteReadChannel;io.kamel.core.config.ResourceConfig;kotlin.coroutines.Continuation<androidx.compose.ui.graphics.painter.Painter>){}kotlin.Any + 21 (SvgDecoder.kt:21)
14                       0xa29c4c kfun:io.kamel.core.decoder.Decoder#decode#suspend(io.ktor.utils.io.ByteReadChannel;io.kamel.core.config.ResourceConfig;kotlin.coroutines.Continuation<1:0>){}kotlin.Any-trampoline + 20 (Decoder.kt:20)
15                       0x8fafa4 kfun:io.kamel.core.object-1.$collect$lambda$0COROUTINE$0.invokeSuspend#internal + 74 (ImageLoading.kt:74)
16                       0x8fb1c8 kfun:io.kamel.core.object-1.$collect$lambda$0$FUNCTION_REFERENCE$8.emit#internal + 59 (ImageLoading.kt:59)
17                       0x9dc25c kfun:kotlinx.coroutines.flow.FlowCollector#emit#suspend(1:0;kotlin.coroutines.Continuation<kotlin.Unit>){}kotlin.Any-trampoline + 31 (FlowCollector.kt:31)
18                       0x4ee3f8 kfun:kotlinx.coroutines.flow.$emitAllImplCOROUTINE$0.invokeSuspend#internal + 33 (Channels.kt:33)
19                       0x4513ac kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 50 (ContinuationImpl.kt:50)
20                       0x4fcdb4 kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1 (Result.kt:1)
21                       0x4fdf7c kfun:kotlinx.coroutines.internal.LimitedDispatcher.Worker.run#internal + 115 (LimitedDispatcher.kt:115)
22                       0x50ce50 kfun:kotlinx.coroutines.MultiWorkerDispatcher.$workerRunLoop$lambda$2COROUTINE$0.invokeSuspend#internal + 99 (MultithreadedDispatchers.kt:99)
23                       0x4513ac kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 50 (ContinuationImpl.kt:50)
24                       0x4fcdb4 kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1 (Result.kt:1)
25                       0x4d055c kfun:kotlinx.coroutines.EventLoopImplBase#processNextEvent(){}kotlin.Long + 15 (ObjectiveCUtils.kt:15)
26                       0x5097e0 kfun:kotlinx.coroutines#runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}0:0 + 49 (EventLoop.common.kt:49)
27                       0x50d344 kfun:kotlinx.coroutines.MultiWorkerDispatcher.$<init>$lambda$1$lambda$0$FUNCTION_REFERENCE$5.$<bridge-UNN>invoke(){}#internal + 119 (MultithreadedDispatchers.kt:119)
28                       0x9cbc28 kfun:kotlin.Function0#invoke(){}1:0-trampoline + 1 ([K][Suspend]Functions:1)
29                       0x456068 WorkerLaunchpad + 107 (Internal.kt:107)
30                       0xace1e0 Worker::processQueueElement(bool) + 9696
31                       0xacdca8 (anonymous namespace)::workerRoutine(void*) + 8360
32 libsystem_pthread.dylib        0x2a90 _pthread_start + 136
33 libsystem_pthread.dylib        0x1fcc thread_start + 8

Coil 3:

0                        0x4f57c XmlSizeOfUnknownEncoding + 2004
1                        0xea5ed8 doContent + 4789716
2                        0xea3d74 contentProcessor + 4781168
3                        0xea2ba8 doProlog + 4776612
4                        0xea021c prologInitProcessor + 4765976
5                        0xea0014 XML_ParseBuffer + 4765456
6                        0xd0a564 SkXMLParser::parse(SkStream&) + 3103840
7                        0xd09d5c SkDOM::build(SkStream&) + 3101784
8                        0xf18988 SkSVGDOM::Builder::make(SkStream&) const + 5259396
9                        0xf0ce80 SkSVGDOM::MakeFromStream(SkStream&) + 5211516
10                       0xf0cda8 org_jetbrains_skia_svg_SVGDOM__1nMakeFromData + 5211300
11                       0x8e0a2c kfun:coil3.svg.SvgDecoder#decode#suspend(kotlin.coroutines.Continuation<coil3.decode.DecodeResult>){}kotlin.Any + 12 (SVGDOM.kt:12)
12                       0x5cbc6c kfun:coil3.intercept.EngineInterceptor.$decodeCOROUTINE$3.invokeSuspend#internal + 20 (Decoder.kt:20)
13                       0x5cca84 kfun:coil3.intercept.EngineInterceptor.$execute$lambda$1$FUNCTION_REFERENCE$1.invoke#internal + 204 (EngineInterceptor.kt:204)
14                       0x923644 kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline + 1 ([K][Suspend]Functions:1)
15                       0x4fc4e4 kfun:kotlinx.coroutines.intrinsics#startUndispatchedOrReturn__at__kotlinx.coroutines.internal.ScopeCoroutine<0:0>(0:1;kotlin.coroutines.SuspendFunction1<0:1,0:0>){0§<kotlin.Any?>;1§<kotlin.Any?>}kotlin.Any? + 72 (IntrinsicsNative.kt:72)
16                       0x4c34f8 kfun:kotlinx.coroutines#withContext#suspend(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>;kotlin.coroutines.Continuation<0:0>){0§<kotlin.Any?>}kotlin.Any? + 155 (Builders.common.kt:155)
17                       0x5cae0c kfun:coil3.intercept.EngineInterceptor.$executeCOROUTINE$1.invokeSuspend#internal + 117 (EngineInterceptor.kt:117)
18                       0x4513b0 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 50 (ContinuationImpl.kt:50)
19                       0x4f8edc kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1 (Result.kt:1)
20                       0x4fa0a4 kfun:kotlinx.coroutines.internal.LimitedDispatcher.Worker.run#internal + 115 (LimitedDispatcher.kt:115)
21                       0x50901c kfun:kotlinx.coroutines.MultiWorkerDispatcher.$workerRunLoop$lambda$2COROUTINE$0.invokeSuspend#internal + 99 (MultithreadedDispatchers.kt:99)
22                       0x4513b0 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 50 (ContinuationImpl.kt:50)
23                       0x4f8edc kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1 (Result.kt:1)
24                       0x4cc6bc kfun:kotlinx.coroutines.EventLoopImplBase#processNextEvent(){}kotlin.Long + 15 (ObjectiveCUtils.kt:15)
25                       0x505908 kfun:kotlinx.coroutines#runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}0:0 + 49 (EventLoop.common.kt:49)
26                       0x509510 kfun:kotlinx.coroutines.MultiWorkerDispatcher.$<init>$lambda$1$lambda$0$FUNCTION_REFERENCE$5.$<bridge-UNN>invoke(){}#internal + 119 (MultithreadedDispatchers.kt:119)
27                       0x9213c4 kfun:kotlin.Function0#invoke(){}1:0-trampoline + 1 ([K][Suspend]Functions:1)
28                       0xa16f14 Worker::processQueueElement(bool) + 9744
29                       0xa169ac (anonymous namespace)::workerRoutine(void*) + 8360
30 libsystem_pthread.dylib        0x2a90 _pthread_start + 136
31 libsystem_pthread.dylib        0x1fcc thread_start + 8

Affected platforms

Versions

To Reproduce Steps and/or the code snippet to reproduce the behavior: Context: KMP project compiled as XcFamework and used in an iOS app.

  1. Use Coil3 or Kamel image loader.
  2. Try to load/show an Svg image (example: https://github.com/Andrew0000/andrew0000.github.io/raw/master/ic_charity.svg)
  3. Also a while color filter is specified (I haven't tested without it)
  4. Crash happens (logs above)

Sample Kamel code:

    val painterResource: Resource<Painter> = asyncPainterResource(url)
    KamelImage(
        modifier = modifier,
        resource = painterResource,
        contentDescription = null,
        colorFilter = ColorFilter.tint(Color.White),
    )

Additional context iOS Simulator (IPhone 11 + iOS 17) on MacBook (Intel chip) doesn't have this crash.

okushnikov commented 1 month ago

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