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.4


On 7/6/2015 10:45 AM, Corinna Vinschen wrote:
Does emacs call setrlimit by any chance?

Yes, that's the problem. The initialization code contains essentially the following:

if (!getrlimit (RLIMIT_STACK, &rlim))
    {
      long newlim;
      /* Approximate the amount regex.c needs per unit of re_max_failures.  */
      int ratio = 20 * sizeof (char *);
      /* Then add 33% to cover the size of the smaller stacks that regex.c
	 successively allocates and discards, on its way to the maximum.  */
      ratio += ratio / 3;
      /* Add in some extra to cover
	 what we're likely to use for other reasons.  */
      newlim = re_max_failures * ratio + 200000;
      if (newlim > rlim.rlim_max)
	{
	  newlim = rlim.rlim_max;
	  /* Don't let regex.c overflow the stack we have.  */
	  re_max_failures = (newlim - 200000) / ratio;
	}
      if (rlim.rlim_cur < newlim)
	rlim.rlim_cur = newlim;

      setrlimit (RLIMIT_STACK, &rlim);
    }

If I disable that code, the problem goes away: rlim_cur is set to the expected 0x7fd000 in handle_sigsegv, and emacs recovers from the stack overflow.

I think I probably should disable that code on Cygwin anyway, because there's simply no need for it. Some time ago I discovered that the default 2MB stack size was not big enough for emacs on Cygwin, and I made emacs use 8MB instead. So there's no need to enlarge it further.

Btw., *if* emacs calls setrlimit and then expects getrlimit to return
the *actual* size of the stack, rather than expecting that rlim_cur is
just a default value when setting up stacks, it's really doing something
borderline.

There's simply *no* guarantee that a stack can be extended to this size.
Any mmap() call could disallow growing the stack beyond its initial
size.  Worse, on Linux you can even mmap so that the stack doesn't
grow to the supposed initial maximum size at all.  The reason is that
Linux doesn't know the concept of "reserved" virtual memory, but the
stack is initially not commited in full either.

If you want to know how big your current stack *actually* is, you can
utilize pthread_getattr_np on Linux and Cygwin, like this:

#include <pthread.h>

   static void
   handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
   {
     pthread_attr_t attr;
     size_t stacksize;

     if (!pthread_getattr_np (pthread_self (), &attr)
	&& !pthread_attr_getstacksize (&attr, &stacksize))
       {
	beg = stack_bottom;
	end = stack_bottom + stack_direction * stacksize;

	[...]

Unfortunately this is non-portable as well, as the trailing _np denotes,
but at least there *is* a reliable method on Linux and Cygwin...

Thanks. That fixes the problem too, even with the call to setrlimit left in. I'll report this to the emacs developers.

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]