This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ANNOUNCEMENT] TEST RELEASE: Cygwin 2.1.0-0.1


Hi Corinna,

On 6/26/2015 10:14 AM, Corinna Vinschen wrote:
Hi Ken,

On Jun 26 08:02, Ken Brown wrote:
On 6/26/2015 7:12 AM, Corinna Vinschen wrote:
On Jun 22 13:08, Corinna Vinschen wrote:
On Jun 21 14:47, Ken Brown wrote:
On 6/20/2015 4:55 PM, Corinna Vinschen wrote:
- First cut of an implementation to allow signal handlers running on an
   alternate signal stack.

- New API sigaltstack, plus definitions for SA_ONSTACK, SS_ONSTACK, SS_DISABLE,
   MINSIGSTKSZ, SIGSTKSZ.
[...]
[...]
did you have a chance to test this a bit, in the meantime?

Yes, but I don't have anything definitive to report yet.  I tried to test a
facility in emacs that uses the alternate stack to recover from stack
overflow (of the main stack) under some circumstances.  The configure script
did detect the alternate stack.

I then made the stack overflow by defining an elisp function that did an
infinite recursion.  emacs still crashed, but the "segmentation fault"
message was printed twice instead of once.  I haven't had a chance yet to
investigate further and try to see what's going on.  What I hope is that the
alternate stack functioned correctly but the code was still not able to
recover for some reason.  I've appended below the signal handler in case you
want to see if you think it ought to work on Cygwin.

Thank you.  I'll try to test this in the next couple of days.  One hint
and one question:

The signal handler:

/* Attempt to recover from SIGSEGV caused by C stack overflow.  */
static void
handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
{
   /* Hard GC error may lead to stack overflow caused by
      too nested calls to mark_object.  No way to survive.  */
   if (!gc_in_progress)
     {
       struct rlimit rlim;

       if (!getrlimit (RLIMIT_STACK, &rlim))

This getrlimit probably won't work as desired.  I just had a quick look
how this request is handled.  It will return the size of the alternate
stack while running the signal handler, rather than the size of the
initial thread's stack as required by POSIX.  This definitely needs
fixing.

	{
	  enum { STACK_DANGER_ZONE = 16 * 1024 };
	  char *beg, *end, *addr;

	  beg = stack_bottom;
	  end = stack_bottom + stack_direction * rlim.rlim_cur;
	  if (beg > end)
	    addr = beg, beg = end, end = addr;
	  addr = (char *) siginfo->si_addr;
	  /* If we're somewhere on stack and too close to
	     one of its boundaries, most likely this is it.  */
	  if (beg < addr && addr < end
	      && (addr - beg < STACK_DANGER_ZONE
		  || end - addr < STACK_DANGER_ZONE))
	    siglongjmp (return_to_command_loop, 1);
	}
     }

   /* Otherwise we can't do anything with this.  */
   deliver_fatal_thread_signal (sig);
}

The code to set up the signal handler on the alternate stack:

static bool
init_sigsegv (void)
{
   struct sigaction sa;
   stack_t ss;

   stack_direction = ((char *) &ss < stack_bottom) ? -1 : 1;

   ss.ss_sp = sigsegv_stack;
   ss.ss_size = sizeof (sigsegv_stack);
                  ^^^^^^^^^^^^^^^^^^^^^^^

What's that size in bytes?

SIGSTKSZ

   ss.ss_flags = 0;
   if (sigaltstack (&ss, NULL) < 0)
     return 0;

   sigfillset (&sa.sa_mask);
   sa.sa_sigaction = handle_sigsegv;
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
   return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1;

Ken

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]