Delete use of signal handlers taking sigcontext arguments.

The configure checks for sigcontext (aka sigcontext_struct) have failed
for a long time without anyone noticing. The MR_GET_FAULT_ADDR macro
that is also needed for the sigcontext code paths was only ever defined
for __i386__ and __mc68000__.

According to the sigaction(2) man page, the struct sigcontext
argument was obsoleted by the introduction of the SA_SIGINFO flag
(which we also have code for, though also not working either).

configure.ac:
    Delete checks related to struct sigcontext.

    Delete check for asm/sigcontext.h

runtime/mercury_conf.h.in:
    Delete macros that are no longer defined.

runtime/mercury_memory_handlers.c:
runtime/mercury_signal.c:
runtime/mercury_signal.h:
    Delete code for using signal handlers that take a sigcontext argument.

    Add XXX where native GC casts a context parameter to
    struct sigcontext * when it should be a ucontext_t *.
    Possibly never tested.

runtime/mercury_faultaddr.h:
    Delete this file containing only the MR_GET_FAULT_ADDR macro which is
    no longer used.

runtime/RESERVED_MACRO_NAMES:
ssdb/RESERVED_MACRO_NAMES:
trace/RESERVED_MACRO_NAMES:
    Delete macros that are no longer defined.

tools/configure_mingw_cross:
    Don't need to set variables mercury_cv_sigcontext_struct_2arg and
    mercury_cv_sigcontext_struct_3arg any more.
This commit is contained in:
Peter Wang
2020-10-12 14:17:15 +11:00
parent c304dd83ad
commit 388938ac1e
10 changed files with 159 additions and 572 deletions

View File

@@ -1456,7 +1456,7 @@ LIBS="$save_LIBS"
MERCURY_CHECK_FOR_HEADERS( \
unistd.h sys/wait.h sys/siginfo.h sys/signal.h ucontext.h \
asm/sigcontext.h sys/param.h sys/time.h sys/times.h \
sys/param.h sys/time.h sys/times.h \
sys/types.h sys/stat.h fcntl.h termios.h sys/ioctl.h \
sys/resource.h sys/stropts.h windows.h dirent.h getopt.h malloc.h \
semaphore.h pthread.h time.h spawn.h fenv.h sys/mman.h sys/sem.h \
@@ -1580,196 +1580,61 @@ fi
#-----------------------------------------------------------------------------#
#
# Check the basics of sigcontext_struct
# Check the basics of siginfo_t
#
AC_MSG_CHECKING(for working \`sigcontext_struct' in second arg)
AC_CACHE_VAL(mercury_cv_sigcontext_struct_2arg,
mercury_cv_sigcontext_struct_2arg=no
AC_TRY_RUN(
[
/* see runtime/mercury_signal.h for documentation of this code */
#define sigcontext_struct sigcontext
#define __KERNEL__
#include <signal.h>
#undef __KERNEL__
#ifdef MR_HAVE_ASM_SIGCONTEXT_H
#include <asm/sigcontext.h>
#endif
#include "mercury_faultaddr.h"
#include <stdio.h>
extern void handler(int signum, struct sigcontext_struct info);
#define FAULT_ADDRESS ((int *)112)
int main() {
signal(SIGSEGV, (void (*)(int))handler);
/* provoke a SIGSEGV */
(*FAULT_ADDRESS)++;
AC_MSG_CHECKING(for \`siginfo_t')
AC_CACHE_VAL(mercury_cv_siginfo_t,
mercury_cv_siginfo_t=no
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#ifdef MR_HAVE_SYS_UCONTEXT_H
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
}
void handler(int signum, struct sigcontext_struct context) {
int *addr;
addr = (int *) MR_GET_FAULT_ADDR(context);
if (signum == SIGSEGV && addr == FAULT_ADDRESS) {
exit(0);
} else {
exit(1);
}
}
],
[mercury_cv_sigcontext_struct_2arg=yes],
[true]))
AC_MSG_RESULT($mercury_cv_sigcontext_struct_2arg)
if test "$mercury_cv_sigcontext_struct_2arg" = no; then
# Check for a sigcontext_struct in the third argument of
# the signal handler (Linux-68k has this).
AC_MSG_CHECKING(for working \`sigcontext_struct' in third arg)
AC_CACHE_VAL(mercury_cv_sigcontext_struct_3arg,
mercury_cv_sigcontext_struct_3arg=no
AC_TRY_RUN(
[
/* see runtime/mercury_signal.h for documentation of this code */
#define sigcontext_struct sigcontext
#define __KERNEL__
#include <signal.h>
#undef __KERNEL__
#ifdef MR_HAVE_ASM_SIGCONTEXT_H
#include <asm/sigcontext.h>
#endif
#include "mercury_faultaddr.h"
#include <stdio.h>
extern void handler(int signum, int code, struct
sigcontext_struct info);
#define FAULT_ADDRESS ((int *)112)
int main() {
signal(SIGSEGV, (void (*)(int))handler);
/* provoke a SIGSEGV */
(*FAULT_ADDRESS)++;
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
}
void handler(int signum, int code, struct sigcontext_struct context) {
int *addr;
addr = (int *) MR_GET_FAULT_ADDR(context);
if (signum == SIGSEGV && addr == FAULT_ADDRESS) {
exit(0);
} else {
exit(1);
}
}
],
[mercury_cv_sigcontext_struct_3arg=yes],
[true]))
AC_MSG_RESULT($mercury_cv_sigcontext_struct_3arg)
else
mercury_cv_sigcontext_struct_3arg=no
fi
mercury_cv_sigcontext_struct=no
if test "$mercury_cv_sigcontext_struct_2arg" = yes; then
mercury_cv_sigcontext_struct=yes
AC_DEFINE(MR_HAVE_SIGCONTEXT_STRUCT_2ARG)
fi
if test "$mercury_cv_sigcontext_struct_3arg" = yes; then
mercury_cv_sigcontext_struct=yes
AC_DEFINE(MR_HAVE_SIGCONTEXT_STRUCT_3ARG)
fi
if test "$mercury_cv_sigcontext_struct" = yes; then
AC_DEFINE(MR_HAVE_SIGCONTEXT_STRUCT)
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
}
],
[mercury_cv_siginfo_t=yes],
[true]))
AC_MSG_RESULT($mercury_cv_siginfo_t)
if test "$mercury_cv_siginfo_t" = yes; then
AC_DEFINE(MR_HAVE_SIGINFO_T)
AC_DEFINE(MR_HAVE_SIGINFO)
# check for sigcontext_struct.eip
AC_MSG_CHECKING(for \`sigcontext_struct' pc access at signals)
AC_MSG_CHECKING(for \`siginfo' pc access at signals)
AC_CACHE_VAL(mercury_cv_pc_access,
mercury_cv_pc_access=no
AC_TRY_RUN(
[
/* see runtime/mercury_signal.h for documentation of this code */
#define sigcontext_struct sigcontext
#define __KERNEL__
#include <signal.h>
#undef __KERNEL__
#ifdef MR_HAVE_ASM_SIGCONTEXT_H
#include <asm/sigcontext.h>
#endif
#include "mercury_faultaddr.h"
#include <stdio.h>
#if MR_HAVE_SIGCONTEXT_STRUCT_3ARG
extern void handler(int signum, int code,
struct sigcontext_struct context);
#else
extern void handler(int signum, struct sigcontext_struct context);
#endif
#define FAULT_ADDRESS ((int *)112)
int main() {
signal(SIGSEGV, (void (*)(int))handler);
/* provoke a SIGSEGV */
(*FAULT_ADDRESS)++;
exit(1);
}
#if MR_HAVE_SIGCONTEXT_STRUCT_3ARG
void handler(int signum, int code, struct sigcontext_struct context) {
#else
void handler(int signum, struct sigcontext_struct context) {
#endif
int *addr;
long pc;
addr = (int *) MR_GET_FAULT_ADDR(context);
pc = (long) context.eip;
if (signum == SIGSEGV && addr == FAULT_ADDRESS && pc != 0) {
exit(0);
} else {
exit(1);
}
}
],
[mercury_cv_pc_access=eip],
[true]))
AC_MSG_RESULT($mercury_cv_pc_access)
if test "$mercury_cv_pc_access" != no; then
AC_DEFINE_UNQUOTED(MR_PC_ACCESS,$mercury_cv_pc_access)
fi
else
AC_MSG_CHECKING(for \`siginfo_t')
AC_CACHE_VAL(mercury_cv_siginfo_t,
mercury_cv_siginfo_t=no
AC_TRY_RUN(
[
#include <stdio.h>
@@ -1777,13 +1642,9 @@ else
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#ifdef MR_HAVE_SYS_UCONTEXT_H
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
@@ -1807,146 +1668,101 @@ else
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
/* Don't use array indexing - the square brackets
are autoconf quote characters */
save_pc = *(((ucontext_t *) context)->uc_mcontext.gregs
+ REG_PC);
}
],
[mercury_cv_siginfo_t=yes],
[true]))
AC_MSG_RESULT($mercury_cv_siginfo_t)
if test "$mercury_cv_siginfo_t" = yes; then
AC_DEFINE(MR_HAVE_SIGINFO_T)
AC_DEFINE(MR_HAVE_SIGINFO)
AC_MSG_CHECKING(for \`siginfo' pc access at signals)
AC_CACHE_VAL(mercury_cv_pc_access,
mercury_cv_pc_access=no
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
/* Don't use array indexing - the square brackets
are autoconf quote characters */
save_pc = *(((ucontext_t *) context)->uc_mcontext.gregs
+ REG_PC);
}
],
[mercury_cv_pc_access=REG_PC;mercury_cv_pc_access_greg=yes],
[true])
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
save_pc = *(((ucontext_t *) context)->uc_mcontext.gregs
+ CTX_EPC);
}
],
[mercury_cv_pc_access=CTX_EPC;mercury_cv_pc_access_greg=yes],
[true])
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
save_pc = ((ucontext_t *) context)->uc_mcontext.sc_pc;
}
],
[mercury_cv_pc_access=sc_pc;mercury_cv_pc_access_greg=no],
[true])
)
AC_MSG_RESULT($mercury_cv_pc_access)
if test "$mercury_cv_pc_access" != no; then
AC_DEFINE_UNQUOTED(MR_PC_ACCESS,$mercury_cv_pc_access)
if test "$mercury_cv_pc_access_greg" != no; then
AC_DEFINE(MR_PC_ACCESS_GREG)
fi
[mercury_cv_pc_access=REG_PC;mercury_cv_pc_access_greg=yes],
[true])
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
save_pc = *(((ucontext_t *) context)->uc_mcontext.gregs
+ CTX_EPC);
}
],
[mercury_cv_pc_access=CTX_EPC;mercury_cv_pc_access_greg=yes],
[true])
AC_TRY_RUN(
[
#include <stdio.h>
#include <signal.h>
#ifdef MR_HAVE_SYS_SIGINFO_H
#include <sys/siginfo.h>
#endif
#ifdef MR_HAVE_UCONTEXT_H
#include <ucontext.h>
#else
#include <sys/ucontext.h>
#endif
int save_signum = 0;
int save_cause;
int save_pc;
extern void handler(int signum, siginfo_t *info, void *context);
int main() {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.$mercury_cv_sigaction_field = handler;
if (sigemptyset(&act.sa_mask) != 0)
exit(1);
if (sigaction(SIGSEGV, &act, NULL) != 0)
exit(1);
if (kill(getpid(), SIGSEGV) != 0)
exit(1);
if (save_signum == 0)
exit(1);
exit(0);
}
void handler(int signum, siginfo_t *info, void *context) {
save_signum = signum;
save_cause = info->si_code;
save_pc = ((ucontext_t *) context)->uc_mcontext.sc_pc;
}
],
[mercury_cv_pc_access=sc_pc;mercury_cv_pc_access_greg=no],
[true])
)
AC_MSG_RESULT($mercury_cv_pc_access)
if test "$mercury_cv_pc_access" != no; then
AC_DEFINE_UNQUOTED(MR_PC_ACCESS,$mercury_cv_pc_access)
if test "$mercury_cv_pc_access_greg" != no; then
AC_DEFINE(MR_PC_ACCESS_GREG)
fi
fi
fi
#-----------------------------------------------------------------------------#
AC_MSG_CHECKING(for an integer type with the same size as a pointer)

View File

@@ -11,12 +11,6 @@
# directory.
#
#-----------------------------------------------------------------------------#
# These are defined by mercury_signal.h. The first is defined only temporarily,
# and the second eliminates gratuitous differences between Linux versions.
# Neither really pollutes the namespace.
__KERNEL__
sigcontext_struct
#-----------------------------------------------------------------------------#
# This is defined on Windows to workaround problems with windows.h.
WIN32_LEAN_AND_MEAN
#-----------------------------------------------------------------------------#

View File

@@ -123,7 +123,6 @@
// MR_HAVE_SYS_SIGNAL_H we have <sys/signal.h>
// MR_HAVE_UCONTEXT_H we have <ucontext.h>
// MR_HAVE_SYS_UCONTEXT_H we have <sys/ucontext.h>
// MR_HAVE_ASM_SIGCONTEXT_H we have <asm/sigcontext.h> (e.g. i386 Linux)
// MR_HAVE_SYS_TIME_H we have <sys/time.h>
// MR_HAVE_UNISTD_H we have <unistd.h>
// MR_HAVE_SYS_PARAM_H we have <sys/param.h>
@@ -158,7 +157,6 @@
#undef MR_HAVE_SYS_SIGNAL_H
#undef MR_HAVE_UCONTEXT_H
#undef MR_HAVE_SYS_UCONTEXT_H
#undef MR_HAVE_ASM_SIGCONTEXT_H
#undef MR_HAVE_SYS_TIME_H
#undef MR_HAVE_UNISTD_H
#undef MR_HAVE_SYS_PARAM_H
@@ -393,22 +391,9 @@
// fault address for SIGSEGVs.
// MR_HAVE_SIGINFO_T defined iff we can figure out the fault address
// for SIGSEGVs using sigaction and siginfo_t.
// MR_HAVE_SIGCONTEXT_STRUCT
// defined iff normal signal handlers are given
// sigcontext_struct arguments that we can use to
// figure out the fault address for SIGSEGVs.
// MR_HAVE_SIGCONTEXT_STRUCT_3ARG
// defined iff signal handlers have three parameters,
// the third being the sigcontext struct.
// MR_HAVE_SIGCONTEXT_STRUCT_2ARG
// defined iff signal handlers have two parameters,
// the second being the sigcontext struct.
#undef MR_HAVE_SIGINFO
#undef MR_HAVE_SIGINFO_T
#undef MR_HAVE_SIGCONTEXT_STRUCT
#undef MR_HAVE_SIGCONTEXT_STRUCT_3ARG
#undef MR_HAVE_SIGCONTEXT_STRUCT_2ARG
// For debugging purposes, if we get a fatal signal, we print out the
// program counter (PC) at which the signal occurred.

View File

@@ -1,54 +0,0 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998-1999 The University of Melbourne.
// Copyright (C) 2016, 2018 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_faultaddr.h:
// Macros for determining the fault address of a signal.
// This is usually non-portable, so architecture specific versions
// are given here, so a single macro can be used elsewhere in the
// system (in particular, this code is necessary both in the
// runtime and in the configuration scripts).
#ifndef MERCURY_FAULT_ADDR_H
#define MERCURY_FAULT_ADDR_H
#if defined(__i386__)
#define MR_GET_FAULT_ADDR(sc) \
((void *) (sc).cr2)
#elif defined(__mc68000__)
#define MR_GET_FAULT_ADDR(sc) \
({ \
struct sigcontext *scp = (struct sigcontext *) sc; \
int format = (scp->sc_formatvec >> 12) & 0xf; \
unsigned long *framedata = (unsigned long *)(scp + 1); \
unsigned long ea; \
if (format == 0xa || format == 0xb) { \
/* 68020/030 */ \
ea = framedata[2]; \
} else if (format == 7) { \
/* 68040 */ \
ea = framedata[3]; \
} else if (format == 4) { \
/* 68060 */ \
ea = framedata[0]; \
if (framedata[1] & 0x08000000) { \
/* Correct addr on misaligned access. */ \
ea = (ea+4095)&(~4095); \
} \
(void *) ea; \
} \
})
#else
// This space deliberately left blank.
//
// We will get a compile error if the macro is used but not defined.
#endif
#endif // not MERCURY_FAULT_ADDR_H

View File

@@ -1,7 +1,7 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998, 2000, 2002, 2005-2007, 2010-2011 The University of Melbourne.
// Copyright (C) 2014-2016, 2018 The Mercury team.
// Copyright (C) 2014-2016, 2018, 2020 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// This module defines the signal handlers for memory zones.
@@ -44,20 +44,12 @@
#include "mercury_trace_base.h"
#include "mercury_memory_zones.h"
#include "mercury_memory_handlers.h"
#include "mercury_faultaddr.h"
#include "mercury_threadscope.h"
////////////////////////////////////////////////////////////////////////////
#ifdef MR_HAVE_SIGINFO
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#if defined(MR_HAVE_SIGCONTEXT_STRUCT_3ARG)
static void complex_sighandler_3arg(int, int,
struct sigcontext_struct);
#else
static void complex_sighandler(int, struct sigcontext_struct);
#endif
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
static void complex_bushandler(int, siginfo_t *, void *);
static void complex_segvhandler(int, siginfo_t *, void *);
#else
@@ -68,15 +60,7 @@
#endif
#ifdef MR_HAVE_SIGINFO
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#if defined(MR_HAVE_SIGCONTEXT_STRUCT_3ARG)
#define bus_handler complex_sighandler_3arg
#define segv_handler complex_sighandler_3arg
#else
#define bus_handler complex_sighandler
#define segv_handler complex_sighandler
#endif
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
#define bus_handler complex_bushandler
#define segv_handler complex_segvhandler
#else
@@ -280,19 +264,7 @@ MR_explain_context(void *the_context)
{
static char buf[100];
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#ifdef MR_PC_ACCESS
struct sigcontext_struct *context = the_context;
void *pc_at_signal = (void *) context->MR_PC_ACCESS;
sprintf(buf, "PC at signal: %ld (%lx)\n",
(long)pc_at_signal, (long)pc_at_signal);
#else
buf[0] = '\0';
#endif
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
#ifdef MR_PC_ACCESS
@@ -316,7 +288,7 @@ MR_explain_context(void *the_context)
#endif // not MR_PC_ACCESS
#else // not MR_HAVE_SIGINFO_T && not MR_HAVE_SIGCONTEXT_STRUCT
#else // not MR_HAVE_SIGINFO_T
buf[0] = '\0';
@@ -325,72 +297,7 @@ MR_explain_context(void *the_context)
return buf;
}
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#if defined(MR_HAVE_SIGCONTEXT_STRUCT_3ARG)
static void
complex_sighandler_3arg(int sig, int code,
struct sigcontext_struct sigcontext)
#else
static void
complex_sighandler(int sig, struct sigcontext_struct sigcontext)
#endif
{
void *address = (void *) MR_GET_FAULT_ADDR(sigcontext);
#ifdef MR_PC_ACCESS
void *pc_at_signal = (void *) sigcontext.MR_PC_ACCESS;
#endif
switch (sig) {
case SIGSEGV:
// If we are debugging, print the segv explanation messages
// before we call MR_try_munprotect. But if we are not debugging,
// only print them if MR_try_munprotect fails.
if (MR_memdebug) {
fflush(stdout);
fprintf(stderr, "\n*** Mercury runtime: "
"caught segmentation violation ***\n");
}
if (MR_try_munprotect(address, &sigcontext)) {
if (MR_memdebug) {
fprintf(stderr, "returning from signal handler\n\n");
}
return;
}
if (!MR_memdebug) {
fflush(stdout);
fprintf(stderr, "\n*** Mercury runtime: "
"caught segmentation violation ***\n");
}
break;
#ifdef SIGBUS
case SIGBUS:
fflush(stdout);
fprintf(stderr, "\n*** Mercury runtime: caught bus error ***\n");
break;
#endif
default:
fflush(stdout);
fprintf(stderr, "\n*** Mercury runtime: "
"caught unknown signal %d ***\n", sig);
break;
}
#ifdef MR_PC_ACCESS
fprintf(stderr, "PC at signal: %ld (%lx)\n",
(long) pc_at_signal, (long) pc_at_signal);
#endif
fprintf(stderr, "address involved: %p\n", address);
MR_trace_report(stderr);
MR_print_dump_stack();
MR_dump_prev_locations();
leave_signal_handler(sig);
} // end complex_sighandler()
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
static void
complex_bushandler(int sig, siginfo_t *info, void *context)
@@ -542,7 +449,7 @@ complex_segvhandler(int sig, siginfo_t *info, void *context)
leave_signal_handler(sig);
} // end complex_segvhandler
#else // not MR_HAVE_SIGINFO_T && not MR_HAVE_SIGCONTEXT_STRUCT
#else // not MR_HAVE_SIGINFO_T
static void
simple_sighandler(int sig)
@@ -572,7 +479,7 @@ simple_sighandler(int sig)
leave_signal_handler(sig);
}
#endif // not MR_HAVE_SIGINFO_T && not MR_HAVE_SIGCONTEXT_STRUCT
#endif // not MR_HAVE_SIGINFO_T
#ifdef MR_MSVC_STRUCTURED_EXCEPTIONS
static const char *MR_find_exception_name(DWORD exception_code);
@@ -844,17 +751,7 @@ static MR_Code *
get_pc_from_context(void *the_context)
{
MR_Code *pc_at_signal = NULL;
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#ifdef MR_PC_ACCESS
struct sigcontext_struct *context = the_context;
pc_at_signal = (MR_Code *) context->MR_PC_ACCESS;
#else
pc_at_signal = (MR_Code *) NULL;
#endif
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
#ifdef MR_PC_ACCESS
@@ -873,7 +770,7 @@ get_pc_from_context(void *the_context)
#endif // not MR_PC_ACCESS
#else // not MR_HAVE_SIGINFO_T && not MR_HAVE_SIGCONTEXT_STRUCT
#else // not MR_HAVE_SIGINFO_T
pc_at_signal = (MR_Code *) NULL;
@@ -897,20 +794,11 @@ get_sp_from_context(void *the_context)
{
MR_Word *sp_at_signal = NULL;
#if defined(MR_NATIVE_GC) && !defined(MR_HIGHLEVEL_CODE)
#if defined(MR_HAVE_SIGCONTEXT_STRUCT)
#ifdef MR_PC_ACCESS
struct sigcontext_struct *context = the_context;
sp_at_signal = (MR_Word *) context->MR_real_reg_number_sp;
#else
sp_at_signal = (MR_Word *) NULL;
#endif
#elif defined(MR_HAVE_SIGINFO_T)
#ifdef MR_HAVE_SIGINFO_T
#ifdef MR_PC_ACCESS
// XXX This probably needs to be cast to ucontext_t instead.
struct sigcontext *context = the_context;
#ifdef MR_PC_ACCESS_GREG
@@ -927,7 +815,7 @@ get_sp_from_context(void *the_context)
#endif // not MR_PC_ACCESS
#else // not MR_HAVE_SIGINFO_T && not MR_HAVE_SIGCONTEXT_STRUCT
#else // not MR_HAVE_SIGINFO_T
sp_at_signal = (MR_Word *) NULL;

View File

@@ -1,7 +1,7 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998,2000,2002, 2006, 2010 The University of Melbourne.
// Copyright (C) 2015-2016, 2018 The Mercury team.
// Copyright (C) 2015-2016, 2018, 2020 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// This module defines functions for setting up signal handlers.
@@ -102,18 +102,14 @@ void
MR_init_signal_action(MR_signal_action *act, MR_Code *handler,
MR_bool need_info, MR_bool restart)
{
#if defined(MR_HAVE_SIGACTION)
#ifdef MR_HAVE_SIGACTION
act->sa_flags = (restart ? SA_RESTART : 0);
if (need_info) {
// If we are using sigcontext struct, it means we have configured
// to not use siginfo, and so when we request signals, we should not
// ask for SA_SIGINFO, since our handler will not be of the right type.
#if !defined(MR_HAVE_SIGCONTEXT_STRUCT)
#ifdef MR_HAVE_SIGINFO_T
act->sa_flags |= SA_SIGINFO;
#endif
#endif
}
if (sigemptyset(&(act->sa_mask)) != 0) {
@@ -123,6 +119,7 @@ MR_init_signal_action(MR_signal_action *act, MR_Code *handler,
errno = 0;
act->MR_SIGACTION_FIELD = handler;
#else // not MR_HAVE_SIGACTION
*act = handler;

View File

@@ -1,15 +1,12 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998, 2000, 2002, 2004-2005, 2010 The University of Melbourne.
// Copyright (C) 2016, 2018 The Mercury team.
// Copyright (C) 2016, 2018, 2020 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_signal.h - functions for setting up signal handlers.
//
// This defines a generic signal handler setup mechanism.
//
// NOTE: If `struct sigcontext' is needed, mercury_signal.h must be
// included before anything which could include <signal.h>.
#ifndef MERCURY_SIGNAL_H
#define MERCURY_SIGNAL_H
@@ -17,31 +14,7 @@
#include "mercury_regs.h" // include before system headers
#include "mercury_conf.h"
#ifdef MR_HAVE_SIGCONTEXT_STRUCT
// Some versions of Linux call it struct sigcontext_struct, some call it
// struct sigcontext. The following #define eliminates the differences.
#define sigcontext_struct sigcontext // must be before #include <signal.h>
struct sigcontext; // this forward decl avoids a gcc warning in signal.h
// On some systems (e.g. most versions of Linux) we need to #define
// __KERNEL__ to get sigcontext_struct from <signal.h>.
// This stuff must come before anything else that might include <signal.h>,
// otherwise the #define __KERNEL__ may not work.
#define __KERNEL__
#include <signal.h> // must come third
#undef __KERNEL__
// Some versions of Linux define it in <signal.h>, others define it in
// <asm/sigcontext.h>. We try both.
#ifdef MR_HAVE_ASM_SIGCONTEXT_H
#include <asm/sigcontext.h>
#endif
#else
#include <signal.h>
#endif
#include <signal.h>
#include "mercury_types.h"
#include "mercury_std.h"

View File

@@ -10,7 +10,3 @@
# directory.
#
#-----------------------------------------------------------------------------#
# These are defined in mercury_signal.h, which ssdb.m #includes.
__KERNEL__
sigcontext_struct
#-----------------------------------------------------------------------------#

View File

@@ -67,8 +67,6 @@ fi
mercury_cv_cc_type=gcc \
mercury_cv_sigaction_field=no \
mercury_cv_sigcontext_struct_2arg=no \
mercury_cv_sigcontext_struct_3arg=no \
mercury_cv_siginfo_t=no \
mercury_cv_is_bigender=no \
mercury_cv_is_littleender=yes \

View File

@@ -10,9 +10,3 @@
# directory.
#
#-----------------------------------------------------------------------------#
# These are defined by mercury_signal.h. The first is defined only temporarily,
# and the second eliminates gratuitous differences between Linux versions.
# Neither really pollutes the namespace.
__KERNEL__
sigcontext_struct
#-----------------------------------------------------------------------------#