emacs-devel
[Top][All Lists]
Advanced

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

Re: Calling Lisp from undo.c's record_* functions


From: Stefan Monnier
Subject: Re: Calling Lisp from undo.c's record_* functions
Date: Mon, 16 Nov 2015 17:51:43 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

> 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

Duh!

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

Not sure what's the best solution, but the precise moment when
run_undoable_change is executed is not terribly important, so if we
could just move it to either before or after the "critical section",
then that would be a good solution.

> 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?

That should work, yes.

> 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?

Nah, that'd be too ugly and brittle.

> 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?

That also sounds risky.


        Stefan



reply via email to

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