Тихое завершение процесса
От: _WerWolf_  
Дата: 08.02.11 09:23
Оценка:
Есть одна проблемка может ктонибуть подскажет как её решить.

В нашем текущем проекте есть один бэкэнд написанный на C++ который иногда может красиво упасть по AccessViolatioException.
И если такое исключение произошло то дальше этот сервис становится нерабочим. После долгих попыток решить эту проблему было решено написать воркэраунд, который будет запускать этот сервис в отдельном процессе и в случае его падения перезапускать процесс.

Проблема IPC была легко решена с помощью WCF. Но появилась новая проблема, если процесс падает, то появляется виндошное окошко мол процесс завершился (Process has stopped working) и действия Закрыть приложение, Поискать решение online, Или оттдебажить программу. (К сожалению не знаю куда залить картинку). Но уверен что все много раз видили это сообщение.
Windows 7 x64 если что.

В результате основное приложение не получает сообщение о том что процесс упал и был закрыт, а значит он не может его перезапустить (так как для него процесс все ещё работает)

В этом собственно и вопрос как заставить процесс упасть тихо без всяких виндошных сообщений?

Немного по деталям реализации, VS 2010, .NET 4.0, Приложение обычное консольное.

Подписка на AppDomain.CurrentDomain.UnhandledException ни к чему не привела, метод вызывает А винда все равно выдает это сообщение о закрытии процесса.

Сейчас буду пробовать вариант с Windows Application вместа Console Application, потому что у класс Application хотябы Exit можно вызвать в случае UnhandledException. Но есть подозрение что это мало поможет

Заранее спасибо если кто-то может поделиться хоть какой-то информацией по этому поводу.
Re: Тихое завершение процесса
От: 1stein Украина  
Дата: 08.02.11 10:15
Оценка:
Здравствуйте, _WerWolf_, Вы писали:

_WW>Есть одна проблемка может ктонибуть подскажет как её решить.


_WW>Заранее спасибо если кто-то может поделиться хоть какой-то информацией по этому поводу.



попробуйте вызвать метод Environment.Exit в обработчике необработанного исключения домена

Кроме того, может это поможет:
CLR via CSharp 3rd Edition

Note The CLR considers some exceptions thrown by native code as corrupted state exceptions
(CSEs) because they are usually the result of a bug in the CLR itself or in some native code for
which the managed developer has no control over . By default, the CLR will not let managed code
catch these exceptions and finally blocks will not execute . Here is the list of native Win32
exceptions that are considered CSEs:
EXCEPTION_ACCESS_VIOLATION EXCEPTION_STACK_OVERFLOW
EXCEPTION_ILLEGAL_INSTRUCTION EXCEPTION_IN_PAGE_ERROR
EXCEPTION_INVALID_DISPOSITION EXCEPTION_NONCONTINUABLE_EXCEPTION
EXCEPTION_PRIV_INSTRUCTION STATUS_UNWIND_CONSOLIDATE .
Individual managed methods can override the default and catch these exceptions by applying
the System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute
to the method . In addition, the method must have the System.Security.
SecurityCriticalAttribute applied to it . You can also override the default for an entire
process by setting the legacyCorruptedStateExceptionPolicy element in the application’s
Extensible Markup Language (XML) configuration file to true . The CLR converts most of these
to a System.Runtime.InteropServices.SEHException object except for EXCEPTION_
ACCESS_VIOLATION, which is converted to a System.AccessViolationException object, and
EXCEPTION_STACK_OVERFLOW, which is converted to a System.StackOverflowException
object .

Will code C# for food
Re[2]: Тихое завершение процесса
От: _WerWolf_  
Дата: 08.02.11 11:21
Оценка:
Здравствуйте, 1stein, Вы писали:

1>Здравствуйте, _WerWolf_, Вы писали:


_WW>>Есть одна проблемка может ктонибуть подскажет как её решить.


_WW>>Заранее спасибо если кто-то может поделиться хоть какой-то информацией по этому поводу.



1>попробуйте вызвать метод Environment.Exit в обработчике необработанного исключения домена


Сказачно, помогло, спасибо!!! Не знал про Environment.Exit, поэтому и хотел заюзать Windows Application вместо Console, потому что у Application класса есть меод Exit.

Ещё раз спасибо!!!

И за выдерку из рихтера, когда буду тестировать AccessViolation надеюсь поможет.
Re: Тихое завершение процесса
От: Pavel Dvorkin Россия  
Дата: 08.02.11 11:24
Оценка:
Здравствуйте, _WerWolf_, Вы писали:

_WW>Есть одна проблемка может ктонибуть подскажет как её решить.



#include "stdafx.h"
#include "windows.h"

LONG WINAPI MyUnhandledExceptionFilter(
  __in          struct _EXCEPTION_POINTERS* ExceptionInfo
)
{
    printf("Failed\n");
    return EXCEPTION_EXECUTE_HANDLER;

}


int _tmain(int argc, _TCHAR* argv[])
{
    SetErrorMode(SEM_NOGPFAULTERRORBOX);
    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
    char* p = NULL;
    *p = 0;
    return 0;
}
With best regards
Pavel Dvorkin
Re[2]: Тихое завершение процесса
От: _WerWolf_  
Дата: 10.02.11 09:03
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, _WerWolf_, Вы писали:


_WW>>Есть одна проблемка может ктонибуть подскажет как её решить.



PD>
PD>#include "stdafx.h"
PD>#include "windows.h"

PD>LONG WINAPI MyUnhandledExceptionFilter(
PD>  __in          struct _EXCEPTION_POINTERS* ExceptionInfo
PD>)
PD>{
PD>    printf("Failed\n");
PD>    return EXCEPTION_EXECUTE_HANDLER;

PD>}


PD>int _tmain(int argc, _TCHAR* argv[])
PD>{
PD>    SetErrorMode(SEM_NOGPFAULTERRORBOX);
PD>    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
PD>    char* p = NULL;
PD>    *p = 0;
PD>    return 0;
PD>}


PD>


О спасибо, это решение даже лучше!


    [Flags]
    internal enum ErrorModes : uint
    {
        SystemDefault             = 0x0,
        SemFailCriticalErrors     = 0x0001,
        SemNoAlignmentFaultExcept = 0x0004,
        SemNoGpFaultErrorBox      = 0x0002,
        SemNoOpenFileErrorBox     = 0x8000
    }

    internal class SetErrorModeExtern
    {
        [DllImport("kernel32.dll")]
        public static extern ErrorModes SetErrorMode(ErrorModes uMode);
    }


Ну и соответственно в Main() первая строчка

        private static int Main( string[] args )
        {
            SetErrorModeExtern.SetErrorMode( ErrorModes.SemNoGpFaultErrorBox );


Все красиво тихо закрывается. Супер!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.