[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