Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Aug 2001 02:48:54 +0900
From:      Fuyuhiko Maruyama <fuyuhik8@is.titech.ac.jp>
To:        Daniel Eischen <eischen@vigrid.com>
Cc:        Arun Sharma <arun@sharmas.dhs.org>, hackers@FreeBSD.ORG
Subject:   Re: libc_r, signals and modifying sigcontext
Message-ID:  <55k7zmiwop.wl@tripper.private>
In-Reply-To: <20010729170402.A18538@sharmas.dhs.org>
References:  <20010729011656.A11337@sharmas.dhs.org> <Pine.SUN.3.91.1010729093922.16774A-100000@pcnet1.pcnet.com>

next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Thu_Aug_30_02:48:54_2001-1
Content-Type: text/plain; charset=US-ASCII

Hi all,

I'm also wondering how to use signals to handle runtime exceptions
such as SIGFPE and SIGSEGV in pthread application.  These signals are
often used by implementation of Java VM to handle Java's runtime
exceptions.  Almost same scheme works fine in non-pthread application
but it doesn't in pthread application.

`test.c' gives the simplified version of this problem (the program
assumes x86).  When I use _thread_sys_sigreturn someone suggests, the
first signal is caught by signal handler on the current thread that
cause the exception but signals after second attempts are never caught
on the current thread.  This is because the sigmask for signal handler
thread, the current thread at first signal, is masked at
uthread_sig.c(line 1070) and it isn't recovered when
_thread_sys_sigreturn is called.

So we need `sigreturn' function for libc_r instead of using
_thread_sys_sigreturn.  `uthread_sigreturn.c` gives a simple
implementation of sigreturn for 4.3-STABLE(4.4-RC).  When I use
sigreturn (implemented at `uthread_sigreturn.c') instead
of_thread_sys_sigreturn in `test.c', the program works as I expected.


How do you think to add sigreturn function into libc_r?

P.S.
The manual page for sigreturn.2 is too old.

--
Fuyuhiko MARUYAMA <fuyuhik8@is.titech.ac.jp>
Matsuoka laboratory,
Department of Mathematical and Computing Sciences,
Graduate School of Information Science and Engineering,
Tokyo Institute of Technology.


--Multipart_Thu_Aug_30_02:48:54_2001-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="test.c"
Content-Transfer-Encoding: 7bit

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <sched.h>

static int zero = 0;

static void *
null_pointer_touch(void *args)
{
  int i;
  for (i = 0; i < 5; i++)
    {
      printf("My thread ID = 0x%x, now I touch NULL pointer. #%d\n", (int)pthread_self(), i);
      fflush(stdout);
      *((int *)(zero)) = 1;	/* touching NULL pointer! */
      printf("My thread ID = 0x%x, survived from Segmentation Fault.\n", (int)pthread_self());
      fflush(stdout);
      sched_yield();
    }
  return 0;
}

static int result_by_zerodiv;

static void *
zero_divide(void *args)
{
  int i;
  for (i = 0; i < 5; i++)
    {
      printf("My thread ID = 0x%x, now I divide 7 by %d. #%d\n", (int)pthread_self(), zero, i);
      fflush(stdout);
      result_by_zerodiv = 7 / zero;	/* dividing with zero */
      printf("My thread ID = 0x%x, survived from division by %d.\n", (int)pthread_self(), zero);
      fflush(stdout);
      sched_yield();
    }
  return 0;
}

static void
signal_handler(int sig, siginfo_t *siginfo, void *context)
{
  unsigned char* pc;
  ucontext_t *ucontext = (ucontext_t *)context;
  mcontext_t *mcontext = &ucontext->uc_mcontext; 
  printf("My thread ID = 0x%x, I'm handling signal %d now.\n", (int)pthread_self(), sig);
  fflush(stdout);
  pc = (unsigned char *)mcontext->mc_eip;
  switch (sig) {
  case SIGFPE:
    if (*pc == 0xf7)
      mcontext->mc_eip += 6;
    break;
  case SIGSEGV:
    if (*pc == 0xc7)
      mcontext->mc_eip += 6;
  }
/*  sigreturn(ucontext); */
  _thread_sys_sigreturn(ucontext);
  /* return; */
}

main()
{
  pthread_t null_pointer_thread;
  pthread_t zero_division_thread;
  struct sigaction action;
  int result;

  printf("My thread ID = 0x%x, I'm the main thread.\n", (int)pthread_self());
  fflush(stdout);

  memset(&action, 0, sizeof(struct sigaction));
  action.sa_handler = signal_handler;
  action.sa_flags = SA_SIGINFO;

  sigaction(SIGSEGV, &action, NULL);
  sigaction(SIGFPE, &action, NULL);

  printf("Creating rogue thread.\n");
  fflush(stdout);
  pthread_create(&null_pointer_thread, NULL, null_pointer_touch, NULL);
  pthread_create(&zero_division_thread, NULL, zero_divide, NULL);

  while (result = pthread_join(null_pointer_thread, NULL))
    printf("pthread_join() failed: %d\n", result);

  while (result = pthread_join(zero_division_thread, NULL))
    printf("pthread_join() failed: %d\n", result);
}

--Multipart_Thu_Aug_30_02:48:54_2001-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="uthread_sigreturn.c"
Content-Transfer-Encoding: 7bit

#include <sys/param.h>
#include <sys/types.h>
#include <sys/signalvar.h>
#include <signal.h>

#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"

int
_sigreturn(ucontext_t *uc)
{
	_thread_run->sigmask = uc->uc_sigmask;
	return _thread_sys_sigreturn(uc);
}

__strong_reference(_sigreturn, sigreturn);
#endif

--Multipart_Thu_Aug_30_02:48:54_2001-1--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?55k7zmiwop.wl>