[m-dev.] complex signal handlers

Peter Wang novalazy at gmail.com
Mon Oct 12 12:57:44 AEDT 2020


Some things while looking into the siginfo issue.


<sys/siginfo.h> does not seem to be installed on any half recent Linux
so it is probably useless to test for it any longer.
A few configure tests included the header without protecting with
MR_HAVE_SYS_SIGINFO_H; I will add the guards.


The checks for sigcontext_struct fail on i386 and x86_64 (and would also
fail on arm), thus that code wouldn't have been used for ages.
I'm inclined to delete all the code using sigcontext_struct.

    checking for working `sigcontext_struct' in second arg... no
    checking for working `sigcontext_struct' in third arg... no

If we want to keep it around, we should define the MR_GET_FAULT_ADDR in
runtime/mercury_faultaddr.h for x86_64. Currently it's only defined for
__i386__ and __mc68000__.


After sigcontext_struct we try to use siginfo_t. In that case, we try to
pick out the program counter from the context argument passed to the
signal handler using one of these methods:

  - context->uc_mcontext.gregs[REG_PC]
  - context->uc_mcontext.gregs[CTX_EPC]
    I can't find REG_PC nor CTX_EPC in any header across a bunch of
    Linux distributions I have unpacked. The original code was written
    in 1995 or earlier...

  - context->uc_mcontext.sc_pc
    Seems to be specific to Alpha, judging by the original commit.

I suggest we delete all references to REG_PC, CTX_EPC and sc_pc now.
However, we can add code to pick out the PC on x86_64 (see the attached
program).

Peter
-------------- next part --------------
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <ucontext.h>
#include <sys/ucontext.h>

#define FAULT_ADDRESS ((int *)112)

static void
complex_segvhandler(int sig, siginfo_t *pinfo, void *uc0)
{
    (void) sig;
    const ucontext_t *uc = (const ucontext_t *) uc0;

    fprintf(stderr, "uc RIP: %#llx\n",
	uc->uc_mcontext.gregs[REG_RIP]);

    psiginfo(pinfo, "received signal");
    exit(1);
}

int main()
{
    struct sigaction act;

    act.sa_flags = SA_SIGINFO;
    sigemptyset(& act.sa_mask);
    act.sa_sigaction = complex_segvhandler;

    sigaction(SIGSEGV, &act, NULL);

    /* provoke a SIGSEGV */
    (*FAULT_ADDRESS)++;

    return 0;
}


More information about the developers mailing list