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

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 until this is manually dismissed. This of course prevents the unit tests from ever terminating.

How can this be avoided?


Here's an example dialog in Win7 with the usual settings:

alt text

If I disable the AeDebug registry key, the JIT debugging option goes away:

alt text

If I disable checking for solutions (the only thing I seem to have control over via the control panel), it looks like this, but still appears and still stops the program from dying until the user presses something. WerAddExcludedApplication is documented to also have this effect.

alt text

34
задан Roman Starkov 3 September 2010 в 16:46
поделиться

1 ответ

Единственное решение - перехватить все исключения на очень высоком уровне (для каждого потока) и должным образом завершить приложение (или выполнить другое действие).

Это единственный способ предотвратить выход исключения из вашего приложения и активацию WER.

Дополнение:

Если исключение - это то, чего вы не делаете, за исключением случаев, когда это происходит, вы можете использовать AssertNoThrow (NUnit) или что-то подобное в другой среде модульного тестирования, чтобы заключить код, запускающий дочерние процессы. Таким образом, вы также получите его в своем отчете о модульном тестировании. На мой взгляд, это самое чистое решение, которое я могу придумать.

Дополнение2: Как показывают комментарии ниже, я ошибался: вы не всегда можете поймать асинхронные исключения, это зависит от того, что позволяет среда. В .NET некоторые исключения не могут быть обнаружены, что делает мою идею бесполезной в этом случае ...

Для .NET: существуют сложные обходные пути, связанные с использованием AppDomains, ведущие к выгрузке AppDomain вместо сбоя всего приложения. Жаль ...

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

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


РЕДАКТИРОВАТЬ:

Наконец-то я понял. В .NET 4.0 вы можете добавить атрибут HandleProcessCorruptedStateExceptions из System.Runtime.ExceptionServices в метод, содержащий блок try / catch. Это действительно сработало! Может быть, не рекомендуется, но работает.

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");

        }

    }      
}
5
ответ дан 27 November 2019 в 16:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: