-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


SIGSEGV-

, 07 2017 . 16:47 +

- . C/C++ , . , .


" ? !". , . , , , try/catch . , , .


SIGSEGV- . , . try/catch . : , . , C++ .


POSIX Windows , Windows Structured Exception Handling (SEH). , SEH Vectored Exception Handling (VEH), . , Microsoft, VEH SEH, .. - . VEH - c POSIX , . VEH , .


setjmp/longjmp, - . , thread local storage (TLS), .


, . . . POSIX- :


stack_t ss;
ss.ss_sp = exception_handler_stack;
ss.ss_flags = 0;
ss.ss_size = SIGSTKSZ;
sigaltstack(&ss, 0);

struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_ONSTACK;
sa.sa_handler = signalHandler;

for (int signum : handled_signals)
    sigaction(signum, &sa, &prev_handlers[signum - MIN_SIGNUM]);

: SIGBUS, SIGFPE, SIGILL, SIGSEGV. sigaltstack , , , . stack overflow, . , , , .. . , , , .


Windows :


exception_handler_handle = AddVectoredExceptionHandler(1, vectoredExceptionHandler);

, ( ) - Linux, . , AddVectoredExceptionHandler, , , . .


POSIX :


static void signalHandler(int signum)
{
    if (execution_context) {
        sigset_t signals;
        sigemptyset(&signals);
        sigaddset(&signals, signum);
        sigprocmask(SIG_UNBLOCK, &signals, NULL);
        reinterpret_cast(static_cast(execution_context))->exception_type = signum;
        longjmp(execution_context->environment, 0);
    }
    else if (prev_handlers[signum - MIN_SIGNUM].sa_handler) {
        prev_handlers[signum - MIN_SIGNUM].sa_handler(signum);
    }
    else {
        signal(signum, SIG_DFL);
        raise(signum);
    }
}

, , .. , . , , , try/catch . , , , , .


Windows :


static LONG WINAPI vectoredExceptionHandler(struct _EXCEPTION_POINTERS *_exception_info)
{
    if (!execution_context ||
        _exception_info->ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C ||
        _exception_info->ExceptionRecord->ExceptionCode == 0xE06D7363L /* C++ exception */
    )
        return EXCEPTION_CONTINUE_SEARCH;

    reinterpret_cast(static_cast(execution_context))->dirty = true;
    reinterpret_cast(static_cast(execution_context))->exception_type = _exception_info->ExceptionRecord->ExceptionCode;
    longjmp(execution_context->environment, 0);
}

VEH Windows . OutputDebugString DBG_PRINTEXCEPTION_C. EXCEPTION_CONTINUE_SEARCH, , . C++ , 0xE06D7363L .


POSIX- Windows longjmp, , try catch, .


, C++ try HW_TO_SW_CONVERTER:


#define HW_TO_SW_CONVERTER_UNIQUE_NAME(NAME, LINE) NAME ## LINE
#define HW_TO_SW_CONVERTER_INTERNAL(NAME, LINE) ExecutionContext HW_TO_SW_CONVERTER_UNIQUE_NAME(NAME, LINE); if (setjmp(HW_TO_SW_CONVERTER_UNIQUE_NAME(NAME, LINE).environment)) throw HwException(HW_TO_SW_CONVERTER_UNIQUE_NAME(NAME, LINE))
#define HW_TO_SW_CONVERTER() HW_TO_SW_CONVERTER_INTERNAL(execution_context, __LINE__)

, :


  1. setjmp, .
  2. , setjmp , - longjmp. , C++ HwException, . catch.

:


if (setjmp(environment))
    throw HwException();

setjmp/longjmp . C++ , . longjmp , . , try, - , .


, setjmp / inline. setjmp. , , .


, Windows RemoveVectoredExceptionHandler. , VEH longjmp - . , , . .


, setjmp. TLS, .


:


ExecutionContext::ExecutionContext() : prev_context(execution_context)
{
#if defined(PLATFORM_OS_WINDOWS)
    dirty = false;
#endif
    execution_context = this;
}

ExecutionContext::~ExecutionContext()
{
#if defined(PLATFORM_OS_WINDOWS)
    if (execution_context->dirty)
        RemoveVectoredExceptionHandler(exception_handler_handle);
#endif
    execution_context = execution_context->prev_context;
}

prev_context, try/catch.


GitHub':
https://github.com/kutelev/hwtrycatch


, Windows, Linux, Mac OS X Android:


https://ci.appveyor.com/project/kutelev/hwtrycatch
https://travis-ci.org/kutelev/hwtrycatch


iOS , .


, C. , try/catch C++.


, , , , , SIGSEGV SIGBUS. . , , .

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/332626/

:  

: [1] []
 

:
: 

: ( )

:

  URL