Исключение службы Windows не обработано - PullRequest
3 голосов
/ 25 января 2011

У меня есть обычный C # сервис, основанный на классе ServiceBase. Этот сервис загружается при запуске библиотеки динамических ссылок c ++. Иногда случается, что происходит сбой службы в неуправляемом коде. К сожалению, просмотрщик событий дает только очень краткое описание этого. Вот как выглядит один, если его сообщения:

Приложение: StreamMapService.exe Версия Framework: v4.0.30319 Описание: процесс был прерван из-за необработанного исключения. Информация об исключении: код исключения c0000005, адрес исключения 00000012 ".

С вероятностью 99% проблема заключается в неуправляемом коде. Проблема в том, что это происходит очень редко (обычно один раз в день) и только при запуске в качестве службы. Под отладчиком все ок. Чтобы выяснить проблемный код, я отредактировал свой основной метод следующим образом:

    static void Main()
    {
        try
        {
            if (!Environment.UserInteractive)
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] 
                { 
                    new Service1() 
                };
                ServiceBase.Run(ServicesToRun);
            }
            else
            {
                var services = new Service1();
                services.Start();
                Console.WriteLine("Press return to exit");
                Console.ReadLine();
                services.Stop();
            }
        }
        catch (SEHException e)
        {
            // wrapper for all exceptions having its origin in unmanaged code
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Crash time: {0}\n", DateTime.Now.ToString());
            sb.AppendFormat("\nMessage:\n{0}", e.Message);
            sb.AppendFormat("\nSource: {0}\n", e.Source);
            sb.AppendFormat("Stack trace:\n{0}", e.StackTrace);
            sb.AppendFormat("\nTarget site:{0}", e.TargetSite);

            SmtpClient client = new SmtpClient("mail.domain.com");
            MailAddress from = new MailAddress("sender@domain.com", "sender", System.Text.Encoding.UTF8);
            MailAddress to = new MailAddress("receiver@domain.com");
            MailMessage message = new MailMessage(from, to);
            message.Body = sb.ToString();
            message.Subject = "StreamMapService crash info";
            client.Send(message);
            throw;
        }
    }

Чтобы протестировать этот обработчик исключений, я создал тестовое исключение для некоторой части неуправляемого кода. Все работает нормально, когда я запускаю службу в отладчике или из командной строки.

Я получаю сообщение электронной почты с информацией об исключении (самое важное, что он содержит стек вызовов, где возникло неуправляемое исключение).

Но когда я запускаю эту программу как системную службу (из Панели управления -> Администрирование -> Службы), служба явно выходит из строя (она перестает отвечать на запросы по интерфейсу tcp, а также средство просмотра событий содержит информацию о сбоях), но я не получаю сообщения электронной почты.

Похоже, что обработчик исключений даже не вызывается в этом случае. Я пытался записать информацию об исключении в файл, но это тоже самое происходит.

Таким образом, при запуске из отладчика или из командной строки информация о стеке вызовов записывается правильно. При запуске в качестве системной службы ничего не происходит. Похоже, что обработка исключений не работает правильно в этом состоянии.

1 Ответ

1 голос
/ 25 января 2011

Исключение, вероятно, выдано в другом потоке. Попробуйте добавить следующее перед вашим кодом, чтобы перехватить любые необработанные исключения:

AppDomain.CurrentDomain.UnhandledException += 
  new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Обработчик события должен иметь следующую подпись:

void CurrentDomain_UnhandledException(
    object sender, UnhandledExceptionEventArgs e) {
}
...