bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#27571: #27571; C stack overflow from `prin1' on deeply nested lisp o


From: Keith David Bershatsky
Subject: bug#27571: #27571; C stack overflow from `prin1' on deeply nested lisp object.
Date: Tue, 09 Jan 2018 08:33:36 -0800

Paul:

I will use the layman's approach of performing git hard resets and going back 
in time -- building Emacs 25 and trying the test case.  I used 
vc-region-history on emacs.c for the Emacs 25 branch and came up with just a 
few hits.  I will start chiseling away with the layman's approach as time 
permits and report back with the results.

Keith

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 1564080f0b24551765d7068b9fc02f6e5a78fea3
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Sun Aug 31 19:37:22 2014 -0700

    Clean up extern decls a bit.
    
    * configure.ac (WERROR_CFLAGS): Don't disable -Wnested-externs.
    While we're at it, don't disable -Wlogical-op either.
    * src/bytecode.c: Include blockinput.h and keyboard.h rather
    than rolling their APIs by hand.
    * src/emacs.c: Include regex.h and rely on its and lisp.h's API
    rather than rolling them by hand.
    * src/lastfile.c: Include lisp.h, to check this file's API.
    * src/lisp.h (lisp_eval_depth, my_edata, my_endbss, my_endbss_static):
    New decls.
    * src/regex.h (re_max_failures): New decl.
    * src/unexcw.c, src/unexmacosx.c, src/unexw32.c:
    Rely on lisp.h's API rather than rolling it by hand.
    * src/vm-limit.c (__after_morecore_hook, __morecore, real_morecore):
    Declare at top level, to pacify GCC -Wnested-externs.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -868,34 +866,33 @@
   if (1
 #ifndef CANNOT_DUMP
       && (!noninteractive || initialized)
 #endif
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
-      extern size_t re_max_failures;
       /* 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;
 #ifdef __NetBSD__
       /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
        stack allocation routine for new process that the allocation
        fails if stack limit is not on page boundary.  So, round up the
        new limit to page boundary.  */
       newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize ();
 #endif
       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);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 5e617bc2b62189768814fafd1a875e89a094d3ef
Author: Juanma Barranquero <lekktu@gmail.com>
Date:   Fri Sep 9 03:06:52 2011 +0200

    Whitespace changes.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -830,34 +830,34 @@
   if (1
 #ifndef CANNOT_DUMP
       && (!noninteractive || initialized)
 #endif
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
       extern size_t re_max_failures;
       /* 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;
 #ifdef __NetBSD__
       /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
        stack allocation routine for new process that the allocation
        fails if stack limit is not on page boundary.  So, round up the
        new limit to page boundary.  */
-      newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
+      newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize ();
 #endif
       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);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit fa8459a34e076cacde3b7c259af9b5dd84b60802
Author: Dan Nicolaescu <dann@ics.uci.edu>
Date:   Fri Sep 30 22:38:16 2005 +0000

    * image.c (slurp_file, xbm_read_bitmap_data): Cast to the correct
    type.
    * xterm.c (handle_one_xevent, handle_one_xevent): Likewise.
    
    * unexelf.c (fatal): Fix prototype.
    
    * term.c (fatal): Implement using varargs.
    
    * regex.c (re_char): Move typedef ...
    * regex.h (re_char): ... here.
    (re_iswctype, re_wctype, re_set_whitespace_regexp): New
    prototypes.
    
    * emacs.c (malloc_set_state): Fix return type.
    (endif): Fix type.
    
    * lisp.h (fatal): Add argument types.
    
    * dispextern.h (fatal): Delete prototype.
    
    * systime.h: (make_time): Prototype moved from ...
    * editfns.c (make_time): ... here.
    
    * editfns.c: Move systime.h include after lisp.h.
    * dired.c:
    * xsmfns.c:
    * process.c: Likewise.
    
    * alloc.c (old_malloc_hook, old_realloc_hook, old_realloc_hook):
    Add parameter types.
    (__malloc_hook, __realloc_hook, __free_hook): Fix prototypes.
    (emacs_blocked_free): Change definition to match __free_hook.
    (emacs_blocked_malloc): Change definition to match __malloc_hook.
    (emacs_blocked_realloc): Change definition to match
    __realloc_hook.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -997,34 +997,34 @@
   if (1
 #ifndef CANNOT_DUMP
       && (!noninteractive || initialized)
 #endif
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
-      extern int re_max_failures;
+      extern size_t re_max_failures;
       /* 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;
 #ifdef __NetBSD__
       /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
        stack allocation routine for new process that the allocation
        fails if stack limit is not on page boundary.  So, round up the
        new limit to page boundary.  */
       newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
 #endif
       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);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 03effc232ed9b79aba077d912f17dd844d703e5e
Author: Karl Heuer <kwzh@gnu.org>
Date:   Thu Dec 4 05:53:41 1997 +0000

    (main): Fix the stack-limit code to calculate
    the ratio for re_max_failures accurately and leave some extra slack.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -590,28 +590,34 @@
   if (1
 #ifndef CANNOT_DUMP
       && (!noninteractive || initialized)
 #endif
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
       extern int re_max_failures;
-      /* Approximate the amount regex.c needs, plus some more.  */
-      newlim = re_max_failures * 2 * 20 * sizeof (char *);
+      /* 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;
 #ifdef __NetBSD__
       /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
        stack allocation routine for new process that the allocation
        fails if stack limit is not on page boundary.  So, round up the
        new limit to page boundary.  */
       newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
 #endif
       if (newlim > rlim.rlim_max)
        {
          newlim = rlim.rlim_max;
-         /* Don't let regex.c overflow the stack.  */
-         re_max_failures = newlim / (2 * 20 * sizeof (char *));
+         /* 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);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 6c2935e99fd15a0c10a4a648a09a499076e031c1
Author: Richard M. Stallman <rms@gnu.org>
Date:   Fri Aug 15 05:07:01 1997 +0000

    (main): Update re_max_failures so regex.c won't overflow
    the stack, except when dumping.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -582,20 +585,28 @@
-  /* Extend the stack space available.  */
-  if (!getrlimit (RLIMIT_STACK, &rlim))
+  if (1
+#ifndef CANNOT_DUMP
+      && (!noninteractive || initialized)
+#endif
+      && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
+      extern int re_max_failures;
       /* Approximate the amount regex.c needs, plus some more.  */
-      newlim = 800000 * sizeof (char *);
+      newlim = re_max_failures * 2 * 20 * sizeof (char *);
 #ifdef __NetBSD__
       /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
        stack allocation routine for new process that the allocation
        fails if stack limit is not on page boundary.  So, round up the
        new limit to page boundary.  */
       newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
 #endif
       if (newlim > rlim.rlim_max)
-       newlim = rlim.rlim_max;
+       {
+         newlim = rlim.rlim_max;
+         /* Don't let regex.c overflow the stack.  */
+         re_max_failures = newlim / (2 * 20 * sizeof (char *));
+       }
       if (rlim.rlim_cur < newlim)
        rlim.rlim_cur = newlim;
 
       setrlimit (RLIMIT_STACK, &rlim);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit d0381a7fa3f50d1042a2372eb23b6f03299aaaa5
Author: Richard M. Stallman <rms@gnu.org>
Date:   Wed Jul 9 00:07:19 1997 +0000

    (main) [__NetBSD__]: Round up new stack limit to page bdry.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -581,13 +581,20 @@
   /* Extend the stack space available.  */
   if (!getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
       /* Approximate the amount regex.c needs, plus some more.  */
       newlim = 800000 * sizeof (char *);
+#ifdef __NetBSD__
+      /* NetBSD (at least NetBSD 1.2G and former) has a bug in its
+       stack allocation routine for new process that the allocation
+       fails if stack limit is not on page boundary.  So, round up the
+       new limit to page boundary.  */
+      newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
+#endif
       if (newlim > rlim.rlim_max)
        newlim = rlim.rlim_max;
       if (rlim.rlim_cur < newlim)
        rlim.rlim_cur = newlim;
 
       setrlimit (RLIMIT_STACK, &rlim);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 509a8fcde89b144b6638693f1bbeb854e7aa492c
Author: Richard M. Stallman <rms@gnu.org>
Date:   Mon Feb 3 02:51:09 1997 +0000

    (main): Don't extend stack limit too far.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -553,6 +553,13 @@
   /* Extend the stack space available.  */
   if (!getrlimit (RLIMIT_STACK, &rlim))
     {
-      rlim.rlim_cur = rlim.rlim_max;
+      long newlim;
+      /* Approximate the amount regex.c needs, plus some more.  */
+      newlim = 800000 * sizeof (char *);
+      if (newlim > rlim.rlim_max)
+       newlim = rlim.rlim_max;
+      if (rlim.rlim_cur < newlim)
+       rlim.rlim_cur = newlim;
+
       setrlimit (RLIMIT_STACK, &rlim);
     }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

commit 53c58b5d489f21fdeb5f3d011e34638f8124fb91
Author: Richard M. Stallman <rms@gnu.org>
Date:   Sun Sep 1 20:47:10 1996 +0000

    [HAVE_SETRLIMIT]: Include time.h and resource.h.
    (main) [HAVE_SETRLIMIT]: Call setrlimit to extend the stack limit.
    New local `rlim'.

diff --git a/src/emacs.c b/src/emacs.c
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -504,0 +513,6 @@
+  /* Extend the stack space available.  */
+  if (!getrlimit (RLIMIT_STACK, &rlim))
+    {
+      rlim.rlim_cur = rlim.rlim_max;
+      setrlimit (RLIMIT_STACK, &rlim);
+    }


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DATE:  [01-08-2018 23:53:05] <8 Jan 2018 23:53:05 -0800>
FROM:  Paul Eggert <eggert@cs.ucla.edu>
> 
> * * *
> 
> That commit was a merge commit, and installed all sorts of changes. The patch 
> you sent reverses just part of the commit. It'd be helpful to know the 
> original 
> commit that caused the problem, as opposed to the later merge.
> 
> Also, the patch undoes some fixes, such as integer overflow checking, that 
> we'd 
> like to keep. This is another reason that it'd be helpful to know the 
> original 
> commit. Alternatively, it'd be helpful to know why the patch fixes the bug, 
> so 
> that we can keep that part of the patch without discarding other fixes from 
> the 
> source.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]