emacs-devel
[Top][All Lists]
Advanced

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

dangerous alloca calls


From: Kenichi Handa
Subject: dangerous alloca calls
Date: Thu, 20 Nov 2003 22:01:20 +0900 (JST)
User-agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.2 Emacs/21.3 (sparc-sun-solaris2.6) MULE/5.0 (SAKAKI)

With CVS HEAD emacs on GNU/Linux,
   (mapcar 'car (make-list #x400000 nil))
causes segfault.

The attached patch fixes it.  But, I found such dangerous
alloca calls in several other places.

E.g. (format (make-string #x1000000 32))
     (apply 'car (make-list #x100000 nil))

It seems that it is better that we use a macro something
like this consitently.  What do you think?

#define SAFE_ALLOCA(address, size, unwind_function)             \
  do {                                                          \
    if (size < MAX_ALLOCA)                                      \
      address = alloca (size);                                  \
    else                                                        \
      {                                                         \
        address = xmalloc (size);                               \
        if (unwind_function)                                    \
          record_unwind_protect (unwind_function, Qnil);        \
      }                                                         \
  } while (0)

---
Ken'ichi HANDA
address@hidden

*** fns.c.~1.346.~      Wed Nov 19 20:06:32 2003
--- fns.c       Thu Nov 20 21:26:50 2003
***************
*** 79,84 ****
--- 79,88 ----
  #ifndef HAVE_UNISTD_H
  extern long time ();
  #endif
+ 
+ /* Don't use alloca for bytes larger than this, lest we overflow
+    their stack.  */
+ #define MAX_ALLOCA 16*1024
  
  DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
         doc: /* Return the argument unchanged.  */)
***************
*** 2937,2942 ****
--- 2941,2956 ----
    UNGCPRO;
  }
  
+ static Lisp_Object *mapcar_args;
+ 
+ static Lisp_Object
+ mapcar_unwind (arg)
+      Lisp_Object arg;
+ {
+   xfree (mapcar_args);
+   return Qnil;
+ }
+ 
  DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
         doc: /* Apply FUNCTION to each element of SEQUENCE, and concat the 
results as strings.
  In between each pair of results, stick in SEPARATOR.  Thus, " " as
***************
*** 2951,2963 ****
    register Lisp_Object *args;
    register int i;
    struct gcpro gcpro1;
  
    len = Flength (sequence);
    leni = XINT (len);
    nargs = leni + leni - 1;
    if (nargs < 0) return build_string ("");
  
!   args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
  
    GCPRO1 (separator);
    mapcar1 (leni, args, function, sequence);
--- 2965,2986 ----
    register Lisp_Object *args;
    register int i;
    struct gcpro gcpro1;
+   int nbytes;
+   int count = SPECPDL_INDEX ();
  
    len = Flength (sequence);
    leni = XINT (len);
    nargs = leni + leni - 1;
    if (nargs < 0) return build_string ("");
  
!   nbytes = nargs * sizeof (Lisp_Object);
!   if (nbytes < MAX_ALLOCA)
!     args = (Lisp_Object *) alloca (nbytes);
!   else
!     {
!       args = mapcar_args = (Lisp_Object *) xmalloc (nbytes);
!       record_unwind_protect (mapcar_unwind, Qnil);
!     }
  
    GCPRO1 (separator);
    mapcar1 (leni, args, function, sequence);
***************
*** 2969,2975 ****
    for (i = 1; i < nargs; i += 2)
      args[i] = separator;
  
!   return Fconcat (nargs, args);
  }
  
  DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
--- 2992,3001 ----
    for (i = 1; i < nargs; i += 2)
      args[i] = separator;
  
!   if (nbytes < MAX_ALLOCA)
!     return Fconcat (nargs, args);
!   else
!     return unbind_to (count, Fconcat (nargs, args));
  }
  
  DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
***************
*** 2982,2995 ****
    register Lisp_Object len;
    register int leni;
    register Lisp_Object *args;
  
    len = Flength (sequence);
    leni = XFASTINT (len);
!   args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
  
    mapcar1 (leni, args, function, sequence);
  
!   return Flist (leni, args);
  }
  
  DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
--- 3008,3035 ----
    register Lisp_Object len;
    register int leni;
    register Lisp_Object *args;
+   int nbytes;
+   int count = SPECPDL_INDEX ();
  
    len = Flength (sequence);
    leni = XFASTINT (len);
!   if (leni < 0) return Qnil;
! 
!   nbytes = leni * sizeof (Lisp_Object);
!   if (nbytes < MAX_ALLOCA)
!     args = (Lisp_Object *) alloca (nbytes);
!   else
!     {
!       args = mapcar_args = (Lisp_Object *) xmalloc (nbytes);
!       record_unwind_protect (mapcar_unwind, Qnil);
!     }
  
    mapcar1 (leni, args, function, sequence);
  
!   if (nbytes < MAX_ALLOCA)
!     return Flist (leni, args);
!   else
!     return unbind_to (count, Flist (leni, args));
  }
  
  DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
***************
*** 3603,3612 ****
        c = from[i++];                  \
      }                                 \
    while (IS_BASE64_IGNORABLE (c))
- 
- /* Don't use alloca for regions larger than this, lest we overflow
-    their stack.  */
- #define MAX_ALLOCA 16*1024
  
  /* Table of characters coding the 64 values.  */
  static char base64_value_to_char[64] =
--- 3643,3648 ----




reply via email to

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