How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)

后端 未结 3 1641
时光说笑
时光说笑 2020-11-27 03:33

Our unit tests fire off child processes, and sometimes these child processes crash. When this happens, a Windows Error Reporting dialog pops up, and the process stays alive

3条回答
  •  盖世英雄少女心
    2020-11-27 03:44

    The only solution is to catch all exceptions at a very high level (for each thread) and terminate the application properly (or perform another action).

    This is the only way to prevent the exception from escaping your app and activating WER.

    Addition:

    If the exception is something you do not except to happen you can use an AssertNoThrow(NUnit) or alike in another Unit Test framework to enclose the code firing the child processes. This way you would also get it into your Unit test report. This is in my opinion the cleanest possible solution I can think of.

    Addition2: As the comments below show, I was mistaken: you cannot always catch the asynchronous exceptions, it depends on what the environment allows. In .NET some exceptions are prevented from being caught, what makes my idea worthless in this case...

    For .NET: There are complicated workarounds involving the use of AppDomains, leading to an unload of an AppDomain instead of a crash of the whole application. Too bad...

    http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx

    http://www.develop.com/media/pdfs/developments_archive/AppDomains.pdf


    EDIT:

    I finally got it. With .NET 4.0 You can add the HandleProcessCorruptedStateExceptions attribute from System.Runtime.ExceptionServices to the method containing the try/catch block. This really worked! Maybe not recommended but works.

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Runtime.ExceptionServices;
    
    namespace ExceptionCatching
    {
        public class Test
        {
            public void StackOverflow()
            {
                StackOverflow();
            }
    
            public void CustomException()
            {
                throw new Exception();
            }
    
            public unsafe void AccessViolation()
            {
                byte b = *(byte*)(8762765876);
            }
        }
    
        class Program
        {
            [HandleProcessCorruptedStateExceptions]
            static void Main(string[] args)
            {
                Test test = new Test();
                try {
                    //test.StackOverflow();
                    test.AccessViolation();
                    //test.CustomException();
                }
                catch
                {
                    Console.WriteLine("Caught.");
                }
    
                Console.WriteLine("End of program");
    
            }
    
        }      
    }
    

提交回复
热议问题