SIGSEGV- |
- . 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__)
, :
setjmp
, .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
. . , , .