From 0bbb27fc3f52f87605cfadba62d52b72523b73a5 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 29 May 2014 17:52:47 +0300 Subject: [PATCH] Fix bug #17622 with crashes in mmap routines. src/buffer.c (init_buffer): Accept an argument 'initialized'. [USE_MMAP_FOR_BUFFERS]: If 'initialized' is non-zero, reset mmap_regions and mmap_fd, to avoid referencing stale data from the dump phase. Add an assertion for buffer text of buffers created in temacs before this function is called. (mmap_regions_1, mmap_fd_1): Remove unused variables. src/lisp.h (init_buffer): Update prototype. src/emacs.c (main): Pass 'initialized' as the argument to init_buffer. --- src/ChangeLog | 13 +++++++++++ src/buffer.c | 60 +++++++++++++++++++++++++++++++++++++-------------- src/emacs.c | 3 ++- src/lisp.h | 2 +- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 7665ccb708..33b8257cc1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2014-05-29 Eli Zaretskii + + * buffer.c (init_buffer): Accept an argument 'initialized'. + [USE_MMAP_FOR_BUFFERS]: If 'initialized' is non-zero, reset + mmap_regions and mmap_fd, to avoid referencing stale data from the + dump phase. Add an assertion for buffer text of buffers created + in temacs before this function is called. (Bug#17622) + (mmap_regions_1, mmap_fd_1): Remove unused variables. + + * lisp.h (init_buffer): Update prototype. + + * emacs.c (main): Pass 'initialized' as the argument to init_buffer. + 2014-05-29 Dmitry Antipov * alloc.c (Fgarbage_collect): Fix compilation with diff --git a/src/buffer.c b/src/buffer.c index 3cbb8153bc..909b3779b0 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -4703,11 +4703,6 @@ static struct mmap_region *mmap_regions; static int mmap_fd; -/* Temporary storage for mmap_set_vars, see there. */ - -static struct mmap_region *mmap_regions_1; -static int mmap_fd_1; - /* Page size on this system. */ static int mmap_page_size; @@ -5272,24 +5267,57 @@ init_buffer_once (void) } void -init_buffer (void) +init_buffer (int initialized) { char *pwd; Lisp_Object temp; ptrdiff_t len; #ifdef USE_MMAP_FOR_BUFFERS - { - struct buffer *b; + if (initialized) + { + struct buffer *b; - /* We cannot dump buffers with meaningful addresses that can be - used by the dumped Emacs. We map new memory for them here. */ - FOR_EACH_BUFFER (b) - { - b->text->beg = NULL; - enlarge_buffer_text (b, 0); - } - } +#ifndef WINDOWSNT + /* These must be reset in the dumped Emacs, to avoid stale + references to mmap'ed memory from before the dump. + + WINDOWSNT doesn't need this because it doesn't track mmap'ed + regions by hand (see w32heap.c, which uses system APIs for + that purpose), and thus doesn't use mmap_regions. */ + mmap_regions = NULL; + mmap_fd = -1; +#endif + + /* The dumped buffers reference addresses of buffer text + recorded by temacs, that cannot be used by the dumped Emacs. + We map new memory for their text here. + + Implementation note: the buffers we carry from temacs are: + " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and + " *code-conversion-work*". They are created by + init_buffer_once and init_window_once (which are not called + in the dumped Emacs), and by the first call to coding.c routines. */ + FOR_EACH_BUFFER (b) + { + b->text->beg = NULL; + enlarge_buffer_text (b, 0); + } + } + else + { + struct buffer *b; + + /* Only buffers with allocated buffer text should be present at + this point in temacs. */ + FOR_EACH_BUFFER (b) + { + eassert (b->text->beg != NULL); + } + } +#else /* not USE_MMAP_FOR_BUFFERS */ + /* Avoid compiler warnings. */ + initialized = initialized; #endif /* USE_MMAP_FOR_BUFFERS */ Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); diff --git a/src/emacs.c b/src/emacs.c index fabea11a3b..57f713125e 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1376,7 +1376,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem xputenv ("LANG=C"); #endif - init_buffer (); /* Init default directory of main buffer. */ + /* Init buffer storage and default directory of main buffer. */ + init_buffer (initialized); init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */ diff --git a/src/lisp.h b/src/lisp.h index 62fca16ec3..bbe2e4e9ce 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3951,7 +3951,7 @@ extern bool overlay_touches_p (ptrdiff_t); extern Lisp_Object other_buffer_safely (Lisp_Object); extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); -extern void init_buffer (void); +extern void init_buffer (int); extern void syms_of_buffer (void); extern void keys_of_buffer (void); -- 2.20.1