Skip to content

Commit

Permalink
Disable sigsetjmp for default compilation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
marshallward committed Aug 17, 2022
1 parent 1f1b8ad commit d1f9d38
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
31 changes: 19 additions & 12 deletions ac/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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 <setjmp.h>])
Expand Down
18 changes: 18 additions & 0 deletions src/framework/posix.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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=\"<symbol name>\".'
error stop
end function sigsetjmp_missing

end module posix
2 changes: 1 addition & 1 deletion src/framework/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

! glibc defines sigsetjmp as __sigsetjmp via macro readable from <setjmp.h>.
#ifndef SIGSETJMP_NAME
#define SIGSETJMP_NAME "__sigsetjmp"
#define SIGSETJMP_NAME "sigsetjmp_missing"
#endif

! This should be defined by /usr/include/signal.h
Expand Down

0 comments on commit d1f9d38

Please sign in to comment.