From d1f9d38771249899dda63f503034205a9847662f Mon Sep 17 00:00:00 2001 From: Marshall Ward Date: Wed, 17 Aug 2022 11:18:12 -0400 Subject: [PATCH] Disable sigsetjmp for default compilation The sigsetjmp function is part of the POSIX, but is not required to be defined as a symbol, and may be implemented as a macro. Since Fortran C bindings require a symbol, we cannot bind to macro implementations. The prior implementation assumed a Linux glibc binding of __sigsetjmp (accessed by a `sigsetjmp` macro), but this did not work on BSD and MacOS builds, which have a dedicated `sigsetjmp` symbol. Although the autoconf build included a macro to test and assign the symbol to `SIGSETJMP_NAME`, this did not resolve builds based on mkmf or similar build systems, and would fail to compile. To resolve this, the SIGSETJMP_NAME points to a placeholder function, `sigsetjmp_missing` which permits compilation but raises an error if called. Since this function is only used in our unit testing, and even then only for tests which would otherwise raise FATAL, this change will not disrupt any simulations. However, it does mean that only "power" users who build with either autoconf or `-DSIGSETJMP_NAME=\"...\"` will be able to run the unit tests. In practice, it should be sufficient to direct users to the autoconf builds, and no actual disruptions are expected. --- ac/configure.ac | 31 +++++++++++++++++++------------ src/framework/posix.F90 | 18 ++++++++++++++++++ src/framework/posix.h | 2 +- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/ac/configure.ac b/ac/configure.ac index dc4962307e..8d74d71fbd 100644 --- a/ac/configure.ac +++ b/ac/configure.ac @@ -234,21 +234,28 @@ AC_SUBST([SRC_DIRS], AC_CONFIG_COMMANDS(Makefile.dep, [make depend]) -# setjmp verification +# POSIX verification tests AC_LANG_PUSH([C]) -# Verify that either sigsetjmp (POSIX) or __sigsetjmp (glibc) are available. -AC_CHECK_FUNC([sigsetjmp]) -AS_IF([test "$ac_cv_func_sigsetjmp" == "yes"], [ - SIGSETJMP_NAME="sigsetjmp" -], [ - AC_CHECK_FUNC([__sigsetjmp], [ - SIGSETJMP_NAME="__sigsetjmp" - ], [ - AC_MSG_ERROR([Could not find a symbol for sigsetjmp.]) +# These symbols may be defined as macros, making them inaccessible by Fortran. +# The following exist in BSD and Linux, so we just test for them. +AC_CHECK_FUNC([setjmp], [], [AC_MSG_ERROR([Could not find setjmp.])]) +AC_CHECK_FUNC([longjmp], [], [AC_MSG_ERROR([Could not find longjmp.])]) +AC_CHECK_FUNC([siglongjmp], [], [AC_MSG_ERROR([Could not find siglongjmp.])]) + +# Determine the sigsetjmp symbol. If missing, then point to sigsetjmp_missing. +# +# Supported symbols: +# sigsetjmp POSIX, BSD libc (MacOS) +# __sigsetjmp glibc (Linux) +SIGSETJMP="sigsetjmp_missing" +for sigsetjmp_fn in sigsetjmp __sigsetjmp; do + AC_CHECK_FUNC([${sigsetjmp_fn}], [ + SIGSETJMP=${sigsetjmp_fn} + break ]) -]) -AC_DEFINE_UNQUOTED([SIGSETJMP_NAME], ["$SIGSETJMP_NAME"]) +done +AC_DEFINE_UNQUOTED([SIGSETJMP_NAME], ["${SIGSETJMP}"]) # Determine the size of jmp_buf and sigjmp_buf AC_CHECK_SIZEOF([jmp_buf], [], [#include ]) diff --git a/src/framework/posix.F90 b/src/framework/posix.F90 index 522024071e..142d7634e2 100644 --- a/src/framework/posix.F90 +++ b/src/framework/posix.F90 @@ -344,4 +344,22 @@ subroutine siglongjmp(env, val) call siglongjmp_posix(env, val_c) end subroutine siglongjmp +!> Placeholder function for a missing or unconfigured sigsetjmp +!! +!! The symbol for sigsetjmp can be platform-dependent and may not exist if +!! defined as a macro. This function allows compilation, and reports a runtime +!! error if used in the program. +function sigsetjmp_missing(env, savesigs) result(rc) bind(c) + type(sigjmp_buf), intent(in) :: env + !< Current process state (unused) + integer(kind=c_int), value, intent(in) :: savesigs + !< Enable signal state flag (unused) + integer(kind=c_int) :: rc + !< Function return code (unused) + + print '(a)', 'ERROR: sigsetjmp() is not implemented in this build.' + print '(a)', 'Recompile with autoconf or -DSIGSETJMP_NAME=\"\".' + error stop +end function sigsetjmp_missing + end module posix diff --git a/src/framework/posix.h b/src/framework/posix.h index d60a868a91..96dec57814 100644 --- a/src/framework/posix.h +++ b/src/framework/posix.h @@ -14,7 +14,7 @@ ! glibc defines sigsetjmp as __sigsetjmp via macro readable from . #ifndef SIGSETJMP_NAME -#define SIGSETJMP_NAME "__sigsetjmp" +#define SIGSETJMP_NAME "sigsetjmp_missing" #endif ! This should be defined by /usr/include/signal.h