mirror of https://code.videolan.org/videolan/dav1d
checkasm: Prefer sigsetjmp()/siglongjmp() over SA_NODEFER
Also prefer re-setting the signal handler upon intercept in combination with SA_RESETHAND over re-raising exceptions with the SIG_DFL handler.
This commit is contained in:
parent
8501a4b201
commit
d23e87f7ae
|
@ -36,7 +36,6 @@
|
|||
#include "src/cpu.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#ifndef SIGBUS
|
||||
/* non-standard, use the same value as mingw-w64 */
|
||||
#define SIGBUS 10
|
||||
|
@ -472,15 +471,18 @@ static LONG NTAPI signal_handler(EXCEPTION_POINTERS *const e) {
|
|||
}
|
||||
#endif
|
||||
#else
|
||||
static void signal_handler(int s);
|
||||
|
||||
static const struct sigaction signal_handler_act = {
|
||||
.sa_handler = signal_handler,
|
||||
.sa_flags = SA_RESETHAND,
|
||||
};
|
||||
|
||||
static void signal_handler(const int s) {
|
||||
if (state.catch_signals) {
|
||||
state.catch_signals = 0;
|
||||
sigaction(s, &signal_handler_act, NULL);
|
||||
checkasm_load_context(s);
|
||||
} else {
|
||||
/* fall back to the default signal handler */
|
||||
static const struct sigaction default_sa = { .sa_handler = SIG_DFL };
|
||||
sigaction(s, &default_sa, NULL);
|
||||
raise(s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -671,14 +673,10 @@ int main(int argc, char *argv[]) {
|
|||
SetConsoleMode(con, con_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
#endif
|
||||
#else
|
||||
const struct sigaction sa = {
|
||||
.sa_handler = signal_handler,
|
||||
.sa_flags = SA_NODEFER,
|
||||
};
|
||||
sigaction(SIGBUS, &sa, NULL);
|
||||
sigaction(SIGFPE, &sa, NULL);
|
||||
sigaction(SIGILL, &sa, NULL);
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
sigaction(SIGBUS, &signal_handler_act, NULL);
|
||||
sigaction(SIGFPE, &signal_handler_act, NULL);
|
||||
sigaction(SIGILL, &signal_handler_act, NULL);
|
||||
sigaction(SIGSEGV, &signal_handler_act, NULL);
|
||||
|
||||
const char *const term = getenv("TERM");
|
||||
use_printf_color = term && strcmp(term, "dumb") && isatty(2);
|
||||
|
|
|
@ -33,12 +33,17 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !ARCH_X86_32 && defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#if ARCH_X86_32
|
||||
#include <setjmp.h>
|
||||
typedef jmp_buf checkasm_context;
|
||||
#define checkasm_save_context() checkasm_handle_signal(setjmp(checkasm_context_buf))
|
||||
#define checkasm_load_context(s) longjmp(checkasm_context_buf, s)
|
||||
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
/* setjmp/longjmp on Windows on architectures using SEH (all except x86_32)
|
||||
* will try to use SEH to unwind the stack, which doesn't work for assembly
|
||||
* functions without unwind information. */
|
||||
#include <windows.h>
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
typedef struct { CONTEXT c; int status; } checkasm_context;
|
||||
#define checkasm_save_context() \
|
||||
(checkasm_context_buf.status = 0, \
|
||||
|
@ -54,9 +59,9 @@ typedef void* checkasm_context;
|
|||
#endif
|
||||
#else
|
||||
#include <setjmp.h>
|
||||
typedef jmp_buf checkasm_context;
|
||||
#define checkasm_save_context() checkasm_handle_signal(setjmp(checkasm_context_buf))
|
||||
#define checkasm_load_context(s) longjmp(checkasm_context_buf, s)
|
||||
typedef sigjmp_buf checkasm_context;
|
||||
#define checkasm_save_context() checkasm_handle_signal(sigsetjmp(checkasm_context_buf, 1))
|
||||
#define checkasm_load_context(s) siglongjmp(checkasm_context_buf, s)
|
||||
#endif
|
||||
|
||||
#include "include/common/attributes.h"
|
||||
|
|
Loading…
Reference in New Issue