AvaloniaUI/Avalonia.GIF

Various crashes when changing streams

Geektoolkit opened this issue · 5 comments

I'm working on getting a consistent exception, but it seems like this fails in various ways from hard hanging visual studio when running it under a debugger to segfaults when running it on linux and others. I'll update this if I get more solid exceptions, but in general I believe there is something wrong with the 'changing' of streams. (I'm guessing something in here possibly, but not sure: private static void SourceChanged(AvaloniaPropertyChangedEventArgs e)

I tried adding:
if ((image.gifInstance != null) && (image.gifInstance.Stream != null))
{
image.gifInstance.Stream?.Close();
image.gifInstance.Stream?.Dispose();
}

to see if I could clean up streams I was using..when I'd close the stream on the outside I'd often get exceptions because the stream was in use in the animated gif control. (if there's a way to stop it that may help me).

I also tried just removing the control and then recreating it, but I don't think that was working either...I was simply removing it from the logical tree, so probably leaking controls.

I've been able to repro it with the demo app by simply using the arrow keys and going up and down fairly quickly to force the stream to change. I full screen the app, not sure if that's helpful.. Eventually the app shuts down and visual studio doesn't always catch it.

In my use case I'm making a full screen digital picture display (Dynaframe) that currently shows images and videos. I've had alot of people ask me to play animated gifs as well, so trying to get that in. When it works it's beauitful, I can crossfade the gifs. But on my raspberry pi I get a segfault within about an hour and a half, and on my windows PC I get a crash after 6 hours or so (transitioning images every 10 seconds). The memory usage doesn't climb so I don't think it's a leak, at least not one I'm seeing.

My code looks like the following: (foregroundimage and background image are image controls. gifImage is a xaml control called 'gifImage' in the xaml. ImageString is a path to an animated .gif on a system. It plays through all of the gifs several times over, so I don't believe it's a bad file.

I've reprod this on windows 10 64 bit and a raspberry pi (debian arm 32 bit) running Avalonia 10.12. I've repro'd it in my own code using file streams as well as in the demo code which uses resources.

The xaml:


<gif:GifImage x:Name="gifImage" />

The codebehind:

private void ShowAnimatedGif()
    {

        try
        {
            ImageStream = File.OpenRead(ImageString);
            ImageStream.Seek(0, SeekOrigin.Begin);
            gifImage.SourceStream = ImageStream;
            gifImage.Stretch = foregroundImage.Stretch;
            gifImage.Opacity = 1;
            foregroundImage.Opacity = 0;
            backgroundImage.Opacity = 0;
        }
        catch (Exception exc)
        {
            Logger.LogComment("Exception Rendering animated GIF: " + exc.ToString());
        }
    }

I've tried to figure it outmyself but the crash is often in the decoder code and it'll take me quite a bit to ramp up on that and the gif image format. Hoping someone with more experience in this control can repro it and help me get this working.

Huge thanks for your time and for a great control...when it works it's beautiful :)

Please give me any stacktrace so that i can take a look!

Ok I'll work on that. The last time it was in the decode. I'll work to get more info though as I'd love to have this fixed!

This is what I have in visual studio right now. The exception in VS on windows 10 is currently :System.ExecutionEngineException however I think it's basically something is getting corrupted in memory and wrecking things. here's a screenshot of the VS instance as well in case that helps. If there's anything I can do to help with this please let me know as it would be great for the community and for the app I'm writing to get this working reliabily! But I also understand it may be tricky.

vs

[External Code]
AvaloniaGif.dll!AvaloniaGif.Decoding.GifDecoder.WriteBackBufToFb(System.IntPtr targetPointer) Line 402
at C:\Users\joefa\source\repos\Dynaframepro2\AvaloniaGif\Decoding\GifDecoder.cs(402)
AvaloniaGif.dll!AvaloniaGif.GifInstance.FrameChanged() Line 91
at C:\Users\joefa\source\repos\Dynaframepro2\AvaloniaGif\GifInstance.cs(91)
AvaloniaGif.dll!AvaloniaGif.GifBackgroundWorker.WaitAndRenderNext() Line 256
at C:\Users\joefa\source\repos\Dynaframepro2\AvaloniaGif\GifBackgroundWorker.cs(256)
AvaloniaGif.dll!AvaloniaGif.GifBackgroundWorker.DoStates() Line 182
at C:\Users\joefa\source\repos\Dynaframepro2\AvaloniaGif\GifBackgroundWorker.cs(182)
AvaloniaGif.dll!AvaloniaGif.GifBackgroundWorker.MainLoop() Line 163
at C:\Users\joefa\source\repos\Dynaframepro2\AvaloniaGif\GifBackgroundWorker.cs(163)

Oh here's the watch windows in case this helps as well. I don't see any null pointers or anything obvious.
image

I'm working on figuring this out myself. My belief is that the actual exception may be an AccessViolation here:
Buffer.MemoryCopy(src, targetPointer.ToPointer(), (uint)_backBufferBytes, (uint)_backBufferBytes);

which I'd seen in the past when I was using file streams vs. memory streams. I'm working to investigate if there's a way to protect the memory here against bad or corrupted input. What I'm witnessing is I'm going through a list of gifs and it plays for a few hours going through each, so I believe that it's not a bad file, but a bad state (or maybe a bad file that slowly puts it in a worse and worse state). I'll update if I figure out anything on my side.