unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Keith David Bershatsky <esq@lawlist.com>
To: Paul Eggert <eggert@cs.ucla.edu>
Cc: 27571@debbugs.gnu.org, Noam Postavsky <npostavs@users.sourceforge.net>
Subject: bug#27571: #27571; C stack overflow from `prin1' on deeply nested lisp object.
Date: Tue, 09 Jan 2018 08:33:36 -0800	[thread overview]
Message-ID: <m2wp0rm1pb.wl%esq@lawlist.com> (raw)
In-Reply-To: <m260f9vuyz.wl%esq@lawlist.com>

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.





  parent reply	other threads:[~2018-01-09 16:33 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-04  1:42 bug#27571: Crashing when printing a lisp object Keith David Bershatsky
2017-07-04  2:05 ` npostavs
2017-07-04  2:32 ` Keith David Bershatsky
2017-07-04  3:32   ` npostavs
2020-08-24 14:11     ` Lars Ingebrigtsen
2020-10-01  1:59       ` Lars Ingebrigtsen
2017-07-04  3:49 ` Keith David Bershatsky
2017-07-07  2:46   ` npostavs
2017-07-26  1:14 ` Keith David Bershatsky
2018-01-09  1:38 ` bug#27571: #27571; C stack overflow from `prin1' on deeply nested " Keith David Bershatsky
2018-01-09  7:53   ` Paul Eggert
2018-01-09 12:58   ` bug#27571: " Noam Postavsky
2018-01-09 16:33 ` Keith David Bershatsky [this message]
2018-01-09 16:43 ` Keith David Bershatsky
2018-01-28 21:45   ` Noam Postavsky
2018-01-28 23:23 ` Keith David Bershatsky
2018-01-28 23:43   ` Noam Postavsky
2018-01-28 23:49 ` Keith David Bershatsky
2018-01-29  0:13   ` Noam Postavsky
2018-01-29  4:26 ` Keith David Bershatsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2wp0rm1pb.wl%esq@lawlist.com \
    --to=esq@lawlist.com \
    --cc=27571@debbugs.gnu.org \
    --cc=eggert@cs.ucla.edu \
    --cc=npostavs@users.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).