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

NullReferenceException or ExecutionEngineException during Tiffsave when reporting progress #141

Closed
LionelArn2 opened this issue Sep 22, 2021 · 3 comments
Labels
bug Something isn't working
Milestone

Comments

@LionelArn2
Copy link

Hey there,

First of all, thanks for your work on libvips. Its performance is quite remarkable and it has been most useful :)

I'm running into a recurrent issue when using Tiffsave repeatedly. I created a very simplified version of my code to reproduce the crash:

Random rand = new();
while (true)
{
    NetVips.Image imageSource = NetVips.Image.Tiffload(@"path\to\image.tiff", n: -1);

    imageSource.SetProgress(new Progress<int>());

    imageSource.Tiffsave(@"path\to\output\" + rand.Next().ToString() + ".tiff");
}

During the execution, the following exception gets thrown during Tiffsave:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
An ExecutionEngineException also gets thrown sometimes instead of the NullReferenceException.

These exceptions never occur at the first iteration of the while loop, always at the 2nd or later. They also do not occur if I do not use SetProgress

The tiff image I've been using for this test is of dimensions 25000x5000 with page height 5000 (ushort).

This post #31 mentions a similar issue with codes very similar to the one above. I tried the different codes from this post and did not have any issue, however replacing Dzsave with Tiffsave suffices to create the crash in my case.

Am I doing something wrong?

@kleisauke kleisauke added the bug Something isn't working label Sep 23, 2021
kleisauke added a commit that referenced this issue Sep 23, 2021
The operation cache of libvips could reuse the image after
subsequent use, so we need to free the recorded delegates
until we are sure that the reference count reaches zero.
@kleisauke
Copy link
Owner

Hi @LionelArn2,

You're not doing anything wrong. It looks like a bug, I could reproduce this with:

//Cache.Max = 0;

for (int i = 0; i < 1000; i++)
{
    using Image image = Image.Tiffload(@"Images\sample.tif");
    image.SetProgress(new Progress<int>());
    image.Tiffsave($"{i}.tiff");
}

Uncommenting Cache.Max = 0 makes it work without problems. The reason is that libvips reuses the image from the operation cache after subsequent use, but the connected Enums.Signals.Eval callback handler is released too early causing ExecutionEngineException (or NullReferenceException) to be thrown:

Process terminated. A callback was made on a garbage collected delegate of type 'NetVips!NetVips.Internal.VipsImage+EvalSignal::Invoke'.

Commit 8682c66 should fix this. If you want to test this, you can use the nightly version of NetVips. Add the https://ci.appveyor.com/nuget/net-vips feed in the <packageSources> section of your NuGet.config:

<packageSources>
  <add key="netvips-nightly" value="https://ci.appveyor.com/nuget/net-vips" />
</packageSources>

And update NetVips to 2.0.1 (build number 291 - prerelease). I'll make a new release soon.

@LionelArn2
Copy link
Author

That's great, thanks for your help and the prompt response!

@kleisauke kleisauke added this to the 2.1.0 milestone Nov 14, 2021
@kleisauke
Copy link
Owner

NetVips v2.1.0 is now available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants