From patchwork Tue Jan 9 21:35:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Storsj=C3=B6?= X-Patchwork-Id: 45548 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:bf2f:b0:199:de12:6fa6 with SMTP id gc47csp673103pzb; Tue, 9 Jan 2024 13:35:23 -0800 (PST) X-Google-Smtp-Source: AGHT+IGS7RwppkPUe8Gre/hve2aYB/93xI7AD5LZCJR73lXMjsGlb4LaicdTSP0DgOQkmg1lL40q X-Received: by 2002:a2e:82c7:0:b0:2cd:2444:d2a with SMTP id n7-20020a2e82c7000000b002cd24440d2amr5569ljh.100.1704836123261; Tue, 09 Jan 2024 13:35:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704836123; cv=none; d=google.com; s=arc-20160816; b=KGGorClJvIvNORcXpbbRkmb3+VNb1FQjVDxL2wX7w9d1cfqjQyTBGGDZxwGXtLZXC1 6SmXVKORa9HJWyh6ePBUXTyNwrNQFJNdwFT7shAeB3k6aCaP9/3YCs+6bbNUAKOo3l3r Mmjdkpa99c/HRCoHNIUOs8KRjFS/ba3nsciVREhiTlfw4cgosuQkcILYcmsex5YVDY1X NFtO2+lbNnv972BsSbbjCVZtZKtiqGk2rRRx1qFmC8zilu/uIeFpaW8nTIvNdYXvIUqB WKg+FNfQysso5ZzXp/tc7DgGDFH8FOX4MNvj1E9egXoIGD/zn0atYkwzn4XrWef6Bvgs q2pQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=nolpCNa5VHF0sRJBXMOO7EGZOSqpQPLh49xYuKXyJ4A=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=XFHDGVpEkkV39LVrjvztGzvsHIsm1lmdWYECWZkbQbYFnDnm0W103i0sUDqexNLjxT 1XOFVexdxL/f3uW+WQ1B8c7kX4rnn/1FEd2z0WZfkfYa/1UZ8akGiWz0eMEwLLtWL1Po fqE1MnKPJADb5H8abh4EF5S1c/x4Z0dx3/S1bbTDJuZ4Cbr5p/UpJdsakv16AFSIQ9ST MmkVgoWdQJPzy/BLe+lF6xk2rQ+iRDsG1x/KPODGhDpVyKMvQfTCSn5gSxIaACkC5imO ijIGNRYqmSHbiBU3XrpElCMzzbiuMS8zajJCTJHNMN6cgaGw0umqH1VCXV75svtgxgMP FmZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@martin-st.20230601.gappssmtp.com header.s=20230601 header.b=vkJxONnQ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dm1-20020a05640222c100b0055762093317si1079487edb.316.2024.01.09.13.35.22; Tue, 09 Jan 2024 13:35:23 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@martin-st.20230601.gappssmtp.com header.s=20230601 header.b=vkJxONnQ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0714868CD83; Tue, 9 Jan 2024 23:35:19 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6836B689245 for ; Tue, 9 Jan 2024 23:35:12 +0200 (EET) Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-50eabfac2b7so3789993e87.0 for ; Tue, 09 Jan 2024 13:35:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=martin-st.20230601.gappssmtp.com; s=20230601; t=1704836111; x=1705440911; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=D+sy1cSRJqYRWcbN6McBDfl6ZYitGrt1VgGEv+nNmbs=; b=vkJxONnQtWOaS5nFhjY+xvhU9HRcrTh/JXJIxCFcjstjOLgjCD1F6/QX22ggxLmi/r ZFL8R44y4aLQUee/KSBPBlVTw87QPhP470xLzxDYogIdy405t7IU8jUjliLK5xQytF+V SSQtxBgZwB+kRV1GI3TcZv8lT4AzCljTEIp/veNDwaG4M5PeeioDGz5QGYKZemSdNl4i jN63oKxfalrL9DGjWSaUXzfVKrmoavBB15hY849xIkBn62kdYodaOT8CLma3WhxD3Mqn n/UDQucknSToSdNFJmpRwmIodbEEQPKLTE3LJBzI+8EgEET62vds4vLgRdkUCBWIkhpa NZyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704836111; x=1705440911; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=D+sy1cSRJqYRWcbN6McBDfl6ZYitGrt1VgGEv+nNmbs=; b=Mmv/pyqvXzhJbySBSQ707bwJV86RPMmkvjats75NBm5wnOV/7FCiJeinx1v5ndzRDq OudTqMcIWwiUL0gF8C+7CkPONoABY1liWKgRRrrHGiCkUhvl4DQDxecqfnD3RSJP/FFP Awuj9YkMaTAAkaZOdMglD3vBZSqclHuy/PT8MH1wY4f3nM+VQwzYZwX2W4+O98vGPEsI nWaDhMcoUDnAdZeFeZVFWJTy7V226PFh7dd8CseljrzZViEWel8C26s76L4XuLxMTfvp ixycayZ5YBW/4AszXs1gfrE8fM5/F44mk1bJ0qMxeGDzTVshOH5JDwr/rWEpUFeEsI1X awwQ== X-Gm-Message-State: AOJu0Ywh9PmegY7UYa3IeTjVs0wcwezMy6OiTqEDweg6vPcP783WtRXY MNk1WnJVQzRTg6F+eE8lDQMHgS+5DKmCUw78n71BeOuub0WC X-Received: by 2002:a05:6512:128d:b0:50e:7ae2:570 with SMTP id u13-20020a056512128d00b0050e7ae20570mr2650394lfs.25.1704836111234; Tue, 09 Jan 2024 13:35:11 -0800 (PST) Received: from localhost (host-97-144.parnet.fi. [77.234.97.144]) by smtp.gmail.com with ESMTPSA id x4-20020ac259c4000000b0050e2782e86dsm462314lfn.184.2024.01.09.13.35.10 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2024 13:35:10 -0800 (PST) From: =?utf-8?q?Martin_Storsj=C3=B6?= To: ffmpeg-devel@ffmpeg.org Date: Tue, 9 Jan 2024 23:35:10 +0200 Message-Id: <20240109213510.60050-1-martin@martin.st> X-Mailer: git-send-email 2.39.3 (Apple Git-145) MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] checkasm: Generalize crash handling X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: jluYOHwooPHO This replaces the riscv specific handling from 7212466e735aa187d82f51dadbce957fe3da77f0 (which essentially is reverted, together with 286d6742218ba0235c32876b50bf593cb1986353) with a different implementation of the same (plus a bit more), based on the corresponding feature in dav1d's checkasm, supporting both Unix and Windows. See in particular dav1d commits 0b6ee30eab2400e4f85b735ad29a68a842c34e21 and 0421f787ea592fd2cc74c887f20b8dc31393788b, authored by Henrik Gramner. The overall approach is the same; set up a signal handler, store the state with sigsetjmp, jump out of the crashing function with siglongjmp. The main difference is in what happens when the signal handler is invoked. In the previous implementation, it would resume from right before calling the crashing function, and then skip that call based on the setjmp return value. In the imported implementation from dav1d, we return to right before the check_func() call, which will skip testing the current function (as the pointer is the same as it was before). Other differences are: - Support for other signal handling mechanisms (Windows AddVectoredExceptionHandler) - Using RtlCaptureContext/RtlRestoreContext instead of setjmp/longjmp on Windows with SEH (which adds the design limitation that it doesn't return a value like setjmp does) - Only catching signals once per function - if more than one signal is delivered before signal handling is reenabled, any signal is handled as it would without our handler - Not using an arch specific signal handler written in assembly --- v2: Updated with dav1d changes from https://code.videolan.org/videolan/dav1d/-/merge_requests/1577: - Remodel checkasm_save_context() to return an integer, like setjmp - Don't call checkasm_fail_func within the signal handler - Make the flag catch_signals a volatile sig_atomic_t - Use sigsetjmp/siglongjmp on Unix platforms - Use SA_RESETHAND and call sigaction when the signal is handled to set up a new handler for later signals - Keep using strsignal on __GLIBC__ --- tests/checkasm/checkasm.c | 96 ++++++++++++++++++++++++++++----- tests/checkasm/checkasm.h | 89 +++++++++++++++++++++++------- tests/checkasm/riscv/checkasm.S | 12 ----- 3 files changed, 153 insertions(+), 44 deletions(-) diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 09c961f0c7..994d64e96b 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -42,6 +42,11 @@ #include #endif +#if defined(_WIN32) && !defined(SIGBUS) +/* non-standard, use the same value as mingw-w64 */ +#define SIGBUS 10 +#endif + #if HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE #include #define COLOR_RED FOREGROUND_RED @@ -329,6 +334,7 @@ static struct { const char *cpu_flag_name; const char *test_name; int verbose; + volatile sig_atomic_t catch_signals; } state; /* PRNG state */ @@ -630,6 +636,61 @@ static CheckasmFunc *get_func(CheckasmFunc **root, const char *name) return f; } +checkasm_context checkasm_context_buf; + +/* Crash handling: attempt to catch crashes and handle them + * gracefully instead of just aborting abruptly. */ +#ifdef _WIN32 +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +static LONG NTAPI signal_handler(EXCEPTION_POINTERS *e) { + int s; + + if (!state.catch_signals) + return EXCEPTION_CONTINUE_SEARCH; + + switch (e->ExceptionRecord->ExceptionCode) { + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + s = SIGFPE; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + s = SIGILL; + break; + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_STACK_OVERFLOW: + s = SIGSEGV; + break; + case EXCEPTION_IN_PAGE_ERROR: + s = SIGBUS; + break; + default: + return EXCEPTION_CONTINUE_SEARCH; + } + state.catch_signals = 0; + checkasm_load_context(s); + return EXCEPTION_CONTINUE_EXECUTION; /* never reached, but shuts up gcc */ +} +#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(int s) { + if (state.catch_signals) { + state.catch_signals = 0; + sigaction(s, &signal_handler_act, NULL); + checkasm_load_context(s); + } +} +#endif + /* Perform tests and benchmarks for the specified cpu flag if supported by the host */ static void check_cpu_flag(const char *name, int flag) { @@ -740,18 +801,20 @@ int main(int argc, char *argv[]) unsigned int seed = av_get_random_seed(); int i, ret = 0; +#ifdef _WIN32 +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + AddVectoredExceptionHandler(0, signal_handler); +#endif +#else + sigaction(SIGBUS, &signal_handler_act, NULL); + sigaction(SIGFPE, &signal_handler_act, NULL); + sigaction(SIGILL, &signal_handler_act, NULL); + sigaction(SIGSEGV, &signal_handler_act, NULL); +#endif #if ARCH_ARM && HAVE_ARMV5TE_EXTERNAL if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags())) checkasm_checked_call = checkasm_checked_call_vfp; #endif -#if ARCH_RISCV && HAVE_RV - struct sigaction act = { - .sa_handler = checkasm_handle_signal, - .sa_flags = 0, - }; - - sigaction(SIGILL, &act, NULL); -#endif if (!tests[0].func || !cpus[0].flag) { fprintf(stderr, "checkasm: no tests to perform\n"); @@ -879,13 +942,22 @@ void checkasm_fail_func(const char *msg, ...) } } -void checkasm_fail_signal(int signum) -{ +void checkasm_set_signal_handler_state(int enabled) { + state.catch_signals = enabled; +} + +int checkasm_handle_signal(int s) { + if (s) { #ifdef __GLIBC__ - checkasm_fail_func("fatal signal %d: %s", signum, strsignal(signum)); + checkasm_fail_func("fatal signal %d: %s", s, strsignal(s)); #else - checkasm_fail_func("fatal signal %d", signum); + checkasm_fail_func(s == SIGFPE ? "fatal arithmetic error" : + s == SIGILL ? "illegal instruction" : + s == SIGBUS ? "bus error" : + "segmentation fault"); #endif + } + return s; } /* Get the benchmark context of the current function */ diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 11f0487731..bd4d084bcb 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -23,7 +23,6 @@ #ifndef TESTS_CHECKASM_CHECKASM_H #define TESTS_CHECKASM_CHECKASM_H -#include #include #include "config.h" @@ -43,6 +42,37 @@ #include "libavutil/lfg.h" #include "libavutil/timer.h" +#ifdef _WIN32 +#include +#if ARCH_X86_32 +#include +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. */ +typedef struct { CONTEXT c; int status; } checkasm_context; +#define checkasm_save_context() \ + (checkasm_context_buf.status = 0, \ + RtlCaptureContext(&checkasm_context_buf.c), \ + checkasm_handle_signal(checkasm_context_buf.status)) +#define checkasm_load_context(s) \ + (checkasm_context_buf.status = s, \ + RtlRestoreContext(&checkasm_context_buf.c, NULL)) +#else +#define checkasm_context void* +#define checkasm_save_context() 0 +#define checkasm_load_context() do {} while (0) +#endif +#else +#include +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 + void checkasm_check_aacencdsp(void); void checkasm_check_aacpsdsp(void); void checkasm_check_ac3dsp(void); @@ -106,9 +136,11 @@ struct CheckasmPerf; void *checkasm_check_func(void *func, const char *name, ...) av_printf_format(2, 3); int checkasm_bench_func(void); void checkasm_fail_func(const char *msg, ...) av_printf_format(1, 2); -void checkasm_fail_signal(int signum); struct CheckasmPerf *checkasm_get_perf_context(void); void checkasm_report(const char *name, ...) av_printf_format(1, 2); +void checkasm_set_signal_handler_state(int enabled); +int checkasm_handle_signal(int s); +extern checkasm_context checkasm_context_buf; /* float compare utilities */ int float_near_ulp(float a, float b, unsigned max_ulp); @@ -132,7 +164,7 @@ static av_unused void *func_ref, *func_new; #define BENCH_RUNS 1000 /* Trade-off between accuracy and speed */ /* Decide whether or not the specified function needs to be tested */ -#define check_func(func, ...) (func_ref = checkasm_check_func((func_new = func), __VA_ARGS__)) +#define check_func(func, ...) (checkasm_save_context(), func_ref = checkasm_check_func((func_new = func), __VA_ARGS__)) /* Declare the function prototype. The first argument is the return value, the remaining * arguments are the function parameters. Naming parameters is optional. */ @@ -147,7 +179,10 @@ static av_unused void *func_ref, *func_new; #define report checkasm_report /* Call the reference function */ -#define call_ref(...) ((func_type *)func_ref)(__VA_ARGS__) +#define call_ref(...)\ + (checkasm_set_signal_handler_state(1),\ + ((func_type *)func_ref)(__VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #if ARCH_X86 && HAVE_X86ASM /* Verifies that clobbered callee-saved registers are properly saved and restored @@ -180,16 +215,21 @@ void checkasm_stack_clobber(uint64_t clobber, ...); ((cpu_flags) & av_get_cpu_flags()) ? (void *)checkasm_checked_call_emms : \ (void *)checkasm_checked_call; #define CLOB (UINT64_C(0xdeadbeefdeadbeef)) -#define call_new(...) (checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ +#define call_new(...) (checkasm_set_signal_handler_state(1),\ + checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB),\ - checked_call(func_new, 0, 0, 0, 0, 0, __VA_ARGS__)) + checked_call(func_new, 0, 0, 0, 0, 0, __VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #elif ARCH_X86_32 #define declare_new(ret, ...) ret (*checked_call)(void *, __VA_ARGS__) = (void *)checkasm_checked_call; #define declare_new_float(ret, ...) ret (*checked_call)(void *, __VA_ARGS__) = (void *)checkasm_checked_call_float; #define declare_new_emms(cpu_flags, ret, ...) ret (*checked_call)(void *, __VA_ARGS__) = \ ((cpu_flags) & av_get_cpu_flags()) ? (void *)checkasm_checked_call_emms : \ (void *)checkasm_checked_call; -#define call_new(...) checked_call(func_new, __VA_ARGS__) +#define call_new(...)\ + (checkasm_set_signal_handler_state(1),\ + checked_call(func_new, __VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #endif #elif ARCH_ARM && HAVE_ARMV5TE_EXTERNAL /* Use a dummy argument, to offset the real parameters by 2, not only 1. @@ -201,7 +241,10 @@ extern void (*checkasm_checked_call)(void *func, int dummy, ...); #define declare_new(ret, ...) ret (*checked_call)(void *, int dummy, __VA_ARGS__, \ int, int, int, int, int, int, int, int, \ int, int, int, int, int, int, int) = (void *)checkasm_checked_call; -#define call_new(...) checked_call(func_new, 0, __VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0) +#define call_new(...) \ + (checkasm_set_signal_handler_state(1),\ + checked_call(func_new, 0, __VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0));\ + checkasm_set_signal_handler_state(0) #elif ARCH_AARCH64 && !defined(__APPLE__) void checkasm_stack_clobber(uint64_t clobber, ...); void checkasm_checked_call(void *func, ...); @@ -210,35 +253,39 @@ void checkasm_checked_call(void *func, ...); int, int, int, int, int, int, int)\ = (void *)checkasm_checked_call; #define CLOB (UINT64_C(0xdeadbeefdeadbeef)) -#define call_new(...) (checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ +#define call_new(...) (checkasm_set_signal_handler_state(1),\ + checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB),\ checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\ - 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0)) + 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0));\ + checkasm_set_signal_handler_state(0) #elif ARCH_RISCV -void checkasm_set_function(void *, sigjmp_buf); +void checkasm_set_function(void *); void *checkasm_get_wrapper(void); -void checkasm_handle_signal(int signum); #if HAVE_RV && (__riscv_xlen == 64) && defined (__riscv_d) #define declare_new(ret, ...) \ - int checked_call_signum = 0; \ - sigjmp_buf checked_call_jb; \ ret (*checked_call)(__VA_ARGS__) = checkasm_get_wrapper(); #define call_new(...) \ - (checkasm_set_function(func_new, checked_call_jb), \ - (checked_call_signum = sigsetjmp(checked_call_jb, 1)) == 0 \ - ? checked_call(__VA_ARGS__) \ - : (checkasm_fail_signal(checked_call_signum), 0)) + (checkasm_set_signal_handler_state(1),\ + checkasm_set_function(func_new), checked_call(__VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #else #define declare_new(ret, ...) -#define call_new(...) ((func_type *)func_new)(__VA_ARGS__) +#define call_new(...)\ + (checkasm_set_signal_handler_state(1),\ + ((func_type *)func_new)(__VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #endif #else #define declare_new(ret, ...) #define declare_new_float(ret, ...) #define declare_new_emms(cpu_flags, ret, ...) /* Call the function */ -#define call_new(...) ((func_type *)func_new)(__VA_ARGS__) +#define call_new(...)\ + (checkasm_set_signal_handler_state(1),\ + ((func_type *)func_new)(__VA_ARGS__));\ + checkasm_set_signal_handler_state(0) #endif #ifndef declare_new_emms @@ -285,6 +332,7 @@ typedef struct CheckasmPerf { uint64_t tsum = 0;\ int ti, tcount = 0;\ uint64_t t = 0; \ + checkasm_set_signal_handler_state(1);\ for (ti = 0; ti < BENCH_RUNS; ti++) {\ PERF_START(t);\ tfunc(__VA_ARGS__);\ @@ -300,6 +348,7 @@ typedef struct CheckasmPerf { emms_c();\ perf->cycles += t;\ perf->iterations++;\ + checkasm_set_signal_handler_state(0);\ }\ } while (0) #else diff --git a/tests/checkasm/riscv/checkasm.S b/tests/checkasm/riscv/checkasm.S index 971d881157..73ca85f344 100644 --- a/tests/checkasm/riscv/checkasm.S +++ b/tests/checkasm/riscv/checkasm.S @@ -41,7 +41,6 @@ endconst checked_func: .quad 0 - .quad 0 saved_regs: /* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */ @@ -53,7 +52,6 @@ func checkasm_set_function la.tls.ie t0, checked_func add t0, tp, t0 sd a0, (t0) - sd a1, 8(t0) ret endfunc @@ -177,14 +175,4 @@ func checkasm_get_wrapper, v call checkasm_fail_func j 4b endfunc - -func checkasm_handle_signal - mv a1, a0 - la.tls.ie a0, checked_func - add a0, tp, a0 - ld a0, 8(a0) - beqz a0, 8f - tail siglongjmp -8: tail abort /* No jump buffer to go to */ -endfunc #endif