Samuel Thibault, on Mon 14 Nov 2016 01:07:40 +0100, wrote:
> > Once that's been resolved, then we're back to the problem with signal
> > preemptors! libpager/pager-memcpy.c includes the following code:
> >
> > void fault (int signo, long int sigcode, struct sigcontext *scp)
> > {
> > assert (scp->sc_error == EKERN_MEMORY_ERROR);
> > err = pager_get_error (pager, sigcode - window + offset);
> > n -= sigcode - window;
> > vm_deallocate (mach_task_self (), window, window_size);
> > longjmp (buf, 1);
> > }
> >
> > Since sigcode no longer contains the faulting address (it's in the subcode,
> > remember?)
>
> Mmm, no. For legacy signal handlers (i.e. without SA_SIGINFO), the
> parameters should still be the sigcode: it's
> _hurd_exception2signal_legacy which should be getting called from
> sysdeps/mach/hurd/i386/trampoline.c.
The attached testcase does get the faulting address.
I really believe the issue is related to this:
> Note that there is a
>
> /* XXX what if handler != action->handler (for instance, if a signal
> * preemptor took over) ? */
>
> above. I'd say that when handler != action->handler we should assume
> it's a legacy handler, and make 'action' point to a default-legacy
> sigaction structure, so that it doesn't have SA_SIGINFO, and thus the
> legacy parameters will be passeD.
Samuel
#define _GNU_SOURCE
#include <sys/types.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <hurd.h>
#include <hurd/sigpreempt.h>
char *c = (char*) 0xa0000000;
error_t
do_copy (struct hurd_signal_preemptor *preemptor)
{
fprintf(stderr,"copying\n");
memcpy(c, c+1, 999999);
fprintf(stderr,"copied\n");
}
int main(int argc, char *argv[]) {
jmp_buf buf;
void fault(int signo, long int sigcode, struct sigcontext *scp)
{
fprintf(stderr,"%d %lx %p\n", signo, sigcode, scp);
longjmp(buf, 1);
}
if (setjmp(buf) == 0) {
hurd_catch_signal(sigmask(SIGSEGV) | sigmask(SIGBUS),
(unsigned long) c, (unsigned long) c+1000000,
&do_copy, (sighandler_t) &fault);
}
fprintf(stderr,"done\n");
return 0;
}