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]


On 6/26/2015 4:05 PM, Corinna Vinschen wrote:

[CC Ben, please keep him on the CC in replies.  Thank you]

Hi Ken,

On Jun 26 12:55, Ken Brown wrote:
Hi Corinna,

On 6/26/2015 11:36 AM, Corinna Vinschen wrote:
Thanks.  Another question:  How does emacs compute stack_bottom?

Very near the beginning of main() it does the following:

   char stack_bottom_variable;
   /* Record (approximately) where the stack begins.  */
   stack_bottom = &stack_bottom_variable;

Thank you.

I created an STC with your code snippets and it now works for me
(attached for reference).

First problem was the return value of getrlimit(RLIMIT_STACK).

Second problem is emacs.  The check for an offset of the offending
address in si_addr being less than 16K (STACK_DANGER_ZONE) is
non-portable, putting it mildly.  This might work on 32 bit Cygwin (I
didn't test that), but the value is too low for 64 bit Cygwin.  With
STACK_DANGER_ZONE == 32K the handler works as desired on 64 bit Cygwin.
Part of the reason is probably the _cygtls area of 12K reserved on each
thread's stack, which moves the address of &stack_bottom_variable to a
pretty low value right from the start.  Another the size of the guard
page area on the main thread (16K).

I had a brief email exchange with a collegue of mine.  Ben allowed me to
quote him, so here are the important snippets of his replies:

- Rlimits are an old way of doing a job and they were to a certain
   extent tied up in the pre-thread world of unix processes.  rlimits
   have never been fully implemented on linux with a way that reproduces
   the unix way in the pre-thread era. rlimits have become a bit of a
   historical legacy and are there for posix compliance and code
   compatibility. The posix language was designed to be vague enough that
   all implementations could be made to conform.

- Rather than making the system implementation conform to some
   unspecified behavior, I think it might be a wise idea to fix emacs
   instead. Looking at the code fragment you posted below(*), Iâm not
   entirely convinced that the code would operate as intended on modern
   Linux or Unix. Given that, it may be better to make an implementation
   which does something like the current behavior was intended to do or
   better yet just remove it as a likely latent bug.

(*) Emacs' handle_sigsegv function.

Of course, for testing purposes this is still nice to have, so thank you
for this test, I really appreciate it.

As for getrlimit(RLIMIT_STACK), I changed that as outlined in my former
mail in git.  On second thought, I also changed the values of
MINSIGSTKSZ and SIGSTKSZ.  Instead of 2K and 8K, they are now defined
as 32K and 64K.  The reason is that we then have enough space on the
alternate stack to install a _cygtls area, should the need arise.

I created new developer snapshots on
Please give them a try.

Remember to tweak STACK_DANGER_ZONE.  You'll have to rebuild emacs
anyway due to the change to [MIN]SIGSTKSZ.

Hi Corinna and Ben,

It works now, in the sense that emacs doesn't crash, and it produces the message "Re-entering top level after C stack overflow". I tested both 32-bit and 64-bit Cygwin. My test consisted of evaluating the following in the emacs *scratch* buffer:

(setq max-specpdl-size 83200000
      max-lisp-eval-depth 640000)
(defun foo () (foo))

(The 'setq' is to override emacs's built-in protection against too-deeply nested lisp function calls.)

On the other hand, emacs doesn't really make a full recovery. For example, if I try to call a subprocess (e.g., 'C-x d' to list a directory), I get a fork error:

Debugger entered--Lisp error: (file-error "Doing vfork" "Resource temporarily unavailable")
  call-process("ls" nil nil nil "--dired")
  dired-insert-directory("/home/kbrown/src/emacs/32build/" "-al" nil nil t)
  dired-internal-noselect("~/src/emacs/32build/" nil)
  dired-noselect("~/src/emacs/32build/" nil)
  dired("~/src/emacs/32build/" nil)
  funcall-interactively(dired "~/src/emacs/32build/" nil)
  call-interactively(dired nil nil)

In view of what Ben said, I don't really care about this from the emacs point of view. I mention it only in case it's useful to you for testing the alternate stack.


Problem reports:
Unsubscribe info:

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