unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Calling Lisp from undo.c's record_* functions
@ 2015-11-16 16:46 Eli Zaretskii
  2015-11-16 21:51 ` Phillip Lord
  2015-11-16 22:51 ` Stefan Monnier
  0 siblings, 2 replies; 47+ messages in thread
From: Eli Zaretskii @ 2015-11-16 16:46 UTC (permalink / raw)
  To: Stefan Monnier, Phillip Lord; +Cc: emacs-devel

Bootstrapping Emacs crashed on me today while building python-wy.el.
Emacs segfaulted while trying to access memory outside its address
space.

Debugging uncovered the following sequence of calls:

  . some Lisp calls 'insert' whose argument is a 12K string
  . this eventually calls insert_from_string_1, which enlarges the
    buffer gap to accommodate for the inserted text
  . in the midst of manipulating the gap, insert_from_string_1 calls
    record_insert
  . record_insert calls record_point, which calls run_undoable_change,
    which calls Lisp
  . the Lisp interpreter decides it's a good time to GC and calls
    garbage_collect
  . garbage_collect calls compact_buffer, which decides the buffer in
    which the insertion happened can be compacted (since the gap
    manipulation is not yet done, and it looks like the buffer has a
    lot of slack space), so it shrinks the gap
  . bottom line: the gap was shrunk behind the back of
    insert_from_string_1, which totally doesn't expect that, and
    proceeds doing silly things, like setting the gap size to a large
    negative value, and from there we are on a certain and very short
    path to a crash

This was caused by a recent change that added a call to
run_undoable_change to various functions in undo.c that record
changes; run_undoable_change calls a Lisp function.

My dilemma is: how to fix this cleanly and correctly?

The record_* functions that are affected by this are called from quite
a few places, most of them in insdel.c, but some in other places.  I
didn't audit all of them, but those I did generally manipulate the gap
and have C pointers to buffer text lying around, because they don't
expect any Lisp to be run or GC to happen.  All of those places are
now living dangerously.

Question #1: do we really need to call Lisp from so deep inside the
bowels of buffer manipulation routines?  Is that safe?  Perhaps we
should reimplement undo-auto--undoable-change inC?

Question #2: one solution is inhibit GC in run_undoable_change.  But
since that could run arbitrary Lisp, is that a good idea? what if we
run out of memory?

Question #3: another possible solution is to set the current buffer's
inhibit_shrinking flag around the call to Lisp in run_undoable_change
-- is this better?  Note that this won't prevent GC in general, so the
follow-up question is can insdel.c functions afford a GC while they
run?

Comments?  Suggestions?

TIA



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

end of thread, other threads:[~2015-11-26 10:27 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-16 16:46 Calling Lisp from undo.c's record_* functions Eli Zaretskii
2015-11-16 21:51 ` Phillip Lord
2015-11-16 22:51 ` Stefan Monnier
2015-11-17 12:14   ` Phillip Lord
2015-11-17 13:46     ` Stefan Monnier
2015-11-17 14:42       ` Phillip Lord
2015-11-17 15:40         ` Stefan Monnier
2015-11-17 16:24           ` Eli Zaretskii
2015-11-17 16:49             ` Stefan Monnier
2015-11-17 17:05               ` Eli Zaretskii
2015-11-17 17:34                 ` Stefan Monnier
2015-11-17 18:00                   ` Eli Zaretskii
2015-11-17 19:09                     ` Stefan Monnier
2015-11-17 19:22                       ` Eli Zaretskii
2015-11-17 21:05                     ` Phillip Lord
2015-11-17 21:02               ` Phillip Lord
2015-11-18  2:55                 ` Stefan Monnier
2015-11-18 12:26                   ` Phillip Lord
2015-11-17 16:35         ` Eli Zaretskii
2015-11-17 20:52           ` Phillip Lord
2015-11-18  3:38             ` Eli Zaretskii
2015-11-18  9:56               ` Phillip Lord
2015-11-18 10:49                 ` David Kastrup
2015-11-18 17:30                 ` Eli Zaretskii
2015-11-17 16:40     ` Eli Zaretskii
2015-11-17 16:51       ` Stefan Monnier
2015-11-17 19:44         ` Eli Zaretskii
2015-11-17 21:35           ` Phillip Lord
2015-11-18  2:52           ` Stefan Monnier
2015-11-18  3:49             ` Eli Zaretskii
2015-11-18 12:31               ` Phillip Lord
2015-11-18 17:49                 ` Eli Zaretskii
2015-11-19  1:49                   ` Stefan Monnier
2015-11-19 10:16                   ` Phillip Lord
2015-11-19 15:53                     ` Eli Zaretskii
2015-11-19 17:49                       ` Stefan Monnier
2015-11-19 17:58                         ` Eli Zaretskii
2015-11-19 18:17                           ` Stefan Monnier
2015-11-22 21:44                       ` Phillip Lord
2015-11-22 22:41                         ` John Wiegley
2015-11-23 17:29                           ` Phillip Lord
2015-11-23  3:37                         ` Eli Zaretskii
2015-11-23 17:28                           ` Phillip Lord
2015-11-25 17:43                             ` Eli Zaretskii
2015-11-25 22:51                               ` Richard Stallman
2015-11-26 10:27                               ` Phillip Lord
2015-11-17 21:13       ` Phillip Lord

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