0

Application I'm working on is crashing on close. The application includes C++ native code loaded from dynamic libraries.

The native code starts cleanup through the GC Finalizer Thread, when it's main container (which is a CLR class) is deleted by GC.

After digging a lot, I found that this is purely time related - if I add Sleep(10000) to one of the native cleanup functions that are being ran when application is closing, it will crash. This essentially happens because the entire native part has a check that basically looks like this:

// native library destruction
~MyEntireDll()
{
  if(!EverythingProperlyCleanedUp())
  {
    log("Killed without proper cleanup.");
    CrashOnPurpose();
  }
}

Colleague suggested that this is because when you press the close button in WPF, it will signal the threads to end, and if they do not do it in set amount of time, it kills them the hard way. This means when our native part of the program takes long to clean up, it is killed - but upon being killed like this, destructors of global objects are still called.

We don't want it to be killed without proper cleanup anyway - the fact that we found out thanks to the intentional crash above is a good thing.

My question is, where do I set how long to wait before killing background threads? Can I disable this feature and have my own way of dealing with hangs? I didn't find anything in the documentation, in fact I found no mention of the timeout at all.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Why do you need a sleep in cleanup function? You shouldn't block in finalizer and throw any exceptions – Pavel Anikhouski Feb 12 '20 at 12:18
  • 4
    Handle the Window's [Closing event](https://stackoverflow.com/a/7717394/1136211), do cleanup there, then call Application.Shutdown. – Clemens Feb 12 '20 at 12:19
  • @PavelAnikhouski I do not need a sleep at all. It was just to emulate the issue in a simpler case. In real use, this crash happens when there's too much data to clean up. But to make sure it's not a bug in the native core, I tested the crash with simpler configuration that has simple cleanup, yet the issue still happened once I artificially slowed the cleanup. – Tomáš Zato Feb 12 '20 at 12:40
  • Your colleagues are correct, the CLR applies a 2 second timeout on the finalizer thread at program exit. So you know absolutely nothing about the underlying problem, you merely shot the messenger. Finalization order is not predictable, using Environment.FailFast() is the more reliable way to fire that gun. Quicker than trying to diagnose a unmanaged heap corruption problem anyway. Use Application Verifier to get ahead. – Hans Passant Feb 12 '20 at 14:15
  • @HansPassant I'm not sure if I understand all of your comment, but there's no heap corruption afaik. – Tomáš Zato Feb 13 '20 at 09:00

0 Answers0