diff options
| author | Paul Eggert | 2014-09-22 22:42:47 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-09-22 22:42:47 -0700 |
| commit | cb8e2bfba7e712815203264a0c40bf2da1ff4e64 (patch) | |
| tree | 72b730a1653aa4987e338042b7f5297f9bcf7071 /src | |
| parent | 9949231fb06aa4a2dfa536e9d5125a81424db3a7 (diff) | |
| download | emacs-cb8e2bfba7e712815203264a0c40bf2da1ff4e64.tar.gz emacs-cb8e2bfba7e712815203264a0c40bf2da1ff4e64.zip | |
Fix SAFE_ALLOCA to not exhaust the stack when in a loop.
Problem reported by Dmietry Antipov in thread leading to:
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html
This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP;
the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS
remain unfixed.
* callproc.c (call_process): Save and restore sa_avail.
* lisp.h (USE_SAFE_ALLOCA): Define sa_avail.
(AVAIL_ALLOCA): New macro.
(SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP):
Use it, and check against sa_avail rather than MAX_ALLOCA.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/callproc.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 15 |
3 files changed, 25 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 09426cfbf99..02d7871e884 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2014-09-23 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix SAFE_ALLOCA to not exhaust the stack when in a loop. | ||
| 4 | Problem reported by Dmietry Antipov in thread leading to: | ||
| 5 | http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html | ||
| 6 | This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; | ||
| 7 | the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS | ||
| 8 | remain unfixed. | ||
| 9 | * callproc.c (call_process): Save and restore sa_avail. | ||
| 10 | * lisp.h (USE_SAFE_ALLOCA): Define sa_avail. | ||
| 11 | (AVAIL_ALLOCA): New macro. | ||
| 12 | (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP): | ||
| 13 | Use it, and check against sa_avail rather than MAX_ALLOCA. | ||
| 14 | |||
| 1 | 2014-09-22 Dmitry Antipov <dmantipov@yandex.ru> | 15 | 2014-09-22 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 16 | ||
| 3 | On OSX, do not free font-specific data more than once (Bug#18501). | 17 | On OSX, do not free font-specific data more than once (Bug#18501). |
diff --git a/src/callproc.c b/src/callproc.c index 798f441bdef..4bedf671e83 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -632,6 +632,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 632 | int volatile fd_error_volatile = fd_error; | 632 | int volatile fd_error_volatile = fd_error; |
| 633 | int volatile filefd_volatile = filefd; | 633 | int volatile filefd_volatile = filefd; |
| 634 | ptrdiff_t volatile count_volatile = count; | 634 | ptrdiff_t volatile count_volatile = count; |
| 635 | ptrdiff_t volatile sa_avail_volatile = sa_avail; | ||
| 635 | ptrdiff_t volatile sa_count_volatile = sa_count; | 636 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 636 | char **volatile new_argv_volatile = new_argv; | 637 | char **volatile new_argv_volatile = new_argv; |
| 637 | int volatile callproc_fd_volatile[CALLPROC_FDS]; | 638 | int volatile callproc_fd_volatile[CALLPROC_FDS]; |
| @@ -648,6 +649,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 648 | fd_error = fd_error_volatile; | 649 | fd_error = fd_error_volatile; |
| 649 | filefd = filefd_volatile; | 650 | filefd = filefd_volatile; |
| 650 | count = count_volatile; | 651 | count = count_volatile; |
| 652 | sa_avail = sa_avail_volatile; | ||
| 651 | sa_count = sa_count_volatile; | 653 | sa_count = sa_count_volatile; |
| 652 | new_argv = new_argv_volatile; | 654 | new_argv = new_argv_volatile; |
| 653 | 655 | ||
diff --git a/src/lisp.h b/src/lisp.h index 3795795c49a..21f652b81ac 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4496,12 +4496,15 @@ enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; | |||
| 4496 | extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | 4496 | extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); |
| 4497 | 4497 | ||
| 4498 | #define USE_SAFE_ALLOCA \ | 4498 | #define USE_SAFE_ALLOCA \ |
| 4499 | ptrdiff_t sa_avail = MAX_ALLOCA; \ | ||
| 4499 | ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false | 4500 | ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false |
| 4500 | 4501 | ||
| 4502 | #define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size)) | ||
| 4503 | |||
| 4501 | /* SAFE_ALLOCA allocates a simple buffer. */ | 4504 | /* SAFE_ALLOCA allocates a simple buffer. */ |
| 4502 | 4505 | ||
| 4503 | #define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \ | 4506 | #define SAFE_ALLOCA(size) ((size) <= sa_avail \ |
| 4504 | ? alloca (size) \ | 4507 | ? AVAIL_ALLOCA (size) \ |
| 4505 | : (sa_must_free = true, record_xmalloc (size))) | 4508 | : (sa_must_free = true, record_xmalloc (size))) |
| 4506 | 4509 | ||
| 4507 | /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * | 4510 | /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * |
| @@ -4510,8 +4513,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4510 | 4513 | ||
| 4511 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ | 4514 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ |
| 4512 | do { \ | 4515 | do { \ |
| 4513 | if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ | 4516 | if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \ |
| 4514 | (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ | 4517 | (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \ |
| 4515 | else \ | 4518 | else \ |
| 4516 | { \ | 4519 | { \ |
| 4517 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ | 4520 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ |
| @@ -4543,8 +4546,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4543 | 4546 | ||
| 4544 | #define SAFE_ALLOCA_LISP(buf, nelt) \ | 4547 | #define SAFE_ALLOCA_LISP(buf, nelt) \ |
| 4545 | do { \ | 4548 | do { \ |
| 4546 | if ((nelt) <= MAX_ALLOCA / word_size) \ | 4549 | if ((nelt) <= sa_avail / word_size) \ |
| 4547 | (buf) = alloca ((nelt) * word_size); \ | 4550 | (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ |
| 4548 | else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ | 4551 | else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ |
| 4549 | { \ | 4552 | { \ |
| 4550 | Lisp_Object arg_; \ | 4553 | Lisp_Object arg_; \ |