From: Dmitry Antipov <dmantipov@yandex.ru>
To: Emacs development discussions <emacs-devel@gnu.org>
Subject: Avoid C stack overflow
Date: Thu, 13 Mar 2014 20:42:52 +0400 [thread overview]
Message-ID: <5321E00C.2010107@yandex.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 527 bytes --]
In http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16999 the user, guided by interactive
help and documentation, got a crash caused by C stack overflow. What about an attempt
to avoid such a mess by examining current C stack depth and check it against system
limits, like suggested in the patch below?
For those who cares about MS-Windows, this looks like a rough equivalent to
getrlimit (RLIMIT_STACK,...):
http://stackoverflow.com/questions/21754928/how-to-get-stack-size-and-stack-limit-of-any-thread-using-win32-api
Dmitry
[-- Attachment #2: error_if_c_stack_overflow.patch --]
[-- Type: text/x-patch, Size: 1868 bytes --]
=== modified file 'src/eval.c'
--- src/eval.c 2014-02-10 09:48:17 +0000
+++ src/eval.c 2014-03-13 15:02:10 +0000
@@ -33,6 +33,10 @@
#include "xterm.h"
#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
/* Chain of condition and catch handlers currently in effect. */
struct handler *handlerlist;
@@ -240,6 +244,32 @@
static struct handler handlerlist_sentinel;
+/* C stack overflow protection. */
+
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_STACK)
+
+/* Extra stack space to reserve. */
+#define STACK_EXTRA (128 * 1024)
+
+/* Current C stack slimit. */
+static struct rlimit stack_limit;
+
+#define STACK_GUARD do { \
+ ptrdiff_t stack_size; \
+ if ((char *) &stack_size < stack_bottom) \
+ stack_size = stack_bottom - (char *) &stack_size; \
+ else \
+ stack_size = (char *) &stack_size - stack_bottom; \
+ if (stack_size + STACK_EXTRA > stack_limit.rlim_cur) \
+ error ("Attempt to overflow C stack"); \
+ } while (0)
+
+#else /* !HAVE_GETRLIMIT || !RLIMIT_STACK */
+
+#define STACK_GUARD ((void) 0)
+
+#endif /* HAVE_GETRLIMIT && RLIMIT_STACK */
+
void
init_eval (void)
{
@@ -262,6 +292,10 @@
#endif
/* This is less than the initial value of num_nonmacro_input_events. */
when_entered_debugger = -1;
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_STACK)
+ if (getrlimit (RLIMIT_STACK, &stack_limit))
+ emacs_abort ();
+#endif /* HAVE_GETRLIMIT && RLIMIT_STACK */
}
/* Unwind-protect function used by call_debugger. */
@@ -2060,6 +2094,8 @@
Lisp_Object funcar;
struct gcpro gcpro1, gcpro2, gcpro3;
+ STACK_GUARD;
+
if (SYMBOLP (form))
{
/* Look up its binding in the lexical environment.
@@ -2749,6 +2785,8 @@
register Lisp_Object *internal_args;
ptrdiff_t i;
+ STACK_GUARD;
+
QUIT;
if (++lisp_eval_depth > max_lisp_eval_depth)
next reply other threads:[~2014-03-13 16:42 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-13 16:42 Dmitry Antipov [this message]
2014-03-13 17:38 ` Avoid C stack overflow Eli Zaretskii
2014-03-13 17:57 ` Paul Eggert
2014-03-13 20:56 ` Eli Zaretskii
2014-03-14 7:02 ` Paul Eggert
2014-03-14 5:47 ` Dmitry Antipov
2014-03-14 6:59 ` Paul Eggert
2014-03-14 11:27 ` Dmitry Antipov
2014-03-14 13:05 ` Stefan Monnier
2014-03-14 13:56 ` Paul Eggert
2014-03-14 16:45 ` Stefan
2014-03-15 1:38 ` Stephen J. Turnbull
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5321E00C.2010107@yandex.ru \
--to=dmantipov@yandex.ru \
--cc=emacs-devel@gnu.org \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.