Subject: bug#9006: 24.0.50; Abort in unshow_buffer/kill-buffer

From: Stephen Berman <[email-masked]>
Date: Wed, 06 Jul 2011 21:19:21 +0200

On Wed, 06 Jul 2011 11:25:07 +0200 martin rudalics <[email-masked]> wrote:

>> I was editing a mail in Gnus when Emacs aborted; full backtrace is
>> below.  This happened with all my initialization and customizations, and
>> going by the Lisp backtrace, seems to involve a third-party library I
>> use, tabbar.el.  I had a similar crash yesterday, when I wasn't running
>> under gdb.  In both case Emacs had been running for over 12 hours and
>> seemed quite sluggish.  Just before the abort I had been deleting text,
>> moving point, and Emacs got less and less responsive, so I typed C-g and
>> that's when the abort happened.
>>
>> #0  abort () at /home/steve/bzr/emacs/quickfixes/src/emacs.c:375
>> No locals.
>> #1  0x080a7257 in unshow_buffer (w=0x97ecc40)
>>     at /home/steve/bzr/emacs/quickfixes/src/window.c:1397
>>         buf = 184854789
>>         b = 0xb04a900
>
> There's a comment about a similar case in xdisp.c
>
>   /* Make the echo area buffer current.  Note that for display
>      purposes, it is not necessary that the displayed window's buffer
>      == current_buffer, except for text property lookup.  So, let's
>      only set that buffer temporarily here without doing a full
>      Fset_window_buffer.  We must also change w->pointm, though,
>      because otherwise an assertions in unshow_buffer fails, and Emacs
>      aborts.  */
>
> but I can't find a useful hint in the backtrace.  I don't even
> understand why a buffer should get killed here.

I assume that's because of with-temp-buffer:

(defmacro with-temp-buffer (&rest body)
  "Create a temporary buffer, and evaluate BODY there like `progn'.
See also `with-temp-file' and `with-output-to-string'."
  (declare (indent 0) (debug t))
  (let ((temp-buffer (make-symbol "temp-buffer")))
    `(let ((,temp-buffer (generate-new-buffer " *temp*")))
       ;; FIXME: kill-buffer can change current-buffer in some odd cases.
       (with-current-buffer ,temp-buffer
         (unwind-protect
	     (progn ,@body)
           (and (buffer-name ,temp-buffer)
                (kill-buffer ,temp-buffer)))))))

which is called from tabbar-line-format:

      (with-temp-buffer
        (let ((truncate-partial-width-windows nil)
              (inhibit-modification-hooks t)
              deactivate-mark ;; Prevent deactivation of the mark!
              start)
          (setq truncate-lines nil
                buffer-undo-list t)
          (apply 'insert (tabbar-line-buttons tabset))
          (setq start (point))
          (while (and (cdr elts) ;; Always show the selected tab!
                      (progn
                        (delete-region start (point-max))
                        (goto-char (point-max))
                        (apply 'insert elts)
                        (goto-char (point-min))
                        (> (vertical-motion 1) 0)))
            (tabbar-scroll tabset 1)
            (setq elts (cdr elts)))))

The Lisp backtrace shows vertical-motion being called just before
kill-buffer, which makes Emacs abort.

I induced the abort again, under the same conditions as described above,
and got exactly the same backtrace.  I'll leave the process running for
a few hours before I have to shut down the machine, in case anyone can
offer debugging suggestions.

Steve Berman