[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#891: 23.0.60; Emacs aborts after buffer-swap-text
From: |
Stefan Monnier |
Subject: |
bug#891: 23.0.60; Emacs aborts after buffer-swap-text |
Date: |
Thu, 04 Sep 2008 23:52:45 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) |
> 1. emacs -Q
> 2. Load the library tabbar.el, available from
> http://emhacks.cvs.sourceforge.net/emhacks/emhacks/tabbar.el?revision=1.69&view=markup
> 3. M-x tabbar-mode
> 4. M-: (buffer-swap-text (get-buffer "*Messages*"))
> 5. C-c C-right (tabbar-forward)
> ==> Emacs aborts
> The full backtrace is below. According to the Lisp backtrace, the abort
> occurs during or after switch-to-buffer. Yet typing C-x b after step 4
> above does not make Emacs abort. Moreover, when I directly call any of
> the tabbar.el functions listed in the backtrace and step through them
> with edebug, this also fails to make Emacs abort. Yet the above recipe
> is reliably reproducible.
> (Since the abort occurs in unshow_buffer, my guess, based on a comment
> at line 8314 of xdisp.c, is that switch-to-buffer needs to have
> something like the code in with_echo_area_buffer that changes w->pointm.
> I guess this would go after the call to Fset_buffer in switch-to-buffer,
> but I don't know how to write the code.)
Does the patch below fix the crash you see?
Stefan
=== modified file 'src/buffer.c'
--- src/buffer.c 2008-08-29 15:11:08 +0000
+++ src/buffer.c 2008-09-05 03:51:15 +0000
@@ -2250,6 +2250,27 @@
if (m->buffer == current_buffer)
m->buffer = other_buffer;
}
+ /* Some of the C code expects that w->buffer == w->pointm->buffer.
+ So since we just swapped the markers between the two buffers, we need
+ to undo the effect of this swap for window markers. */
+ {
+ Lisp_Object w = Fselected_window (), ws = Qnil;
+ Lisp_Object buf1, buf2;
+ XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer);
+
+ while (NILP (Fmemq (w, ws)))
+ {
+ ws = Fcons (w, ws);
+ if ((EQ (XWINDOW (w)->buffer, buf1)
+ || EQ (XWINDOW (w)->buffer, buf2))
+ && MARKERP (XWINDOW (w)->pointm))
+ Fset_marker (XWINDOW (w)->pointm,
+ make_number (BUF_BEGV (XBUFFER (XWINDOW (w)->buffer))),
+ XWINDOW (w)->buffer);
+ w = Fnext_window (w, Qt, Qt);
+ }
+ }
+
if (current_buffer->text->intervals)
(eassert (EQ (current_buffer->text->intervals->up.obj, buffer)),
XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));