unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Avoid C stack overflow
@ 2014-03-13 16:42 Dmitry Antipov
  2014-03-13 17:38 ` Eli Zaretskii
  2014-03-13 17:57 ` Paul Eggert
  0 siblings, 2 replies; 12+ messages in thread
From: Dmitry Antipov @ 2014-03-13 16:42 UTC (permalink / raw)
  To: Emacs development discussions

[-- 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)


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-03-15  1:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-13 16:42 Avoid C stack overflow Dmitry Antipov
2014-03-13 17:38 ` 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

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