Subject: 24.3; trapped in an (imaginary) recursive edit
From: Samuel Bronson <[email-masked]>
To: [email-masked]
Date: Mon, 05 May 2014 22:20:11 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

As the comment in temporarily_switch_to_single_kboard () says, it is
possible for lisp code to call `recursive-edit' (or one of its callers)
while the keyboard for the selected frame is locked.  And it is indeed
better to throw an error when this happens than to leave the user with a
frozen screen.  (I don't properly understand the circumstances I saw it
in, but they involved emacs --daemon and a terminal which did not
actually work.)

One small problem: this happens *after* the line:
  command_loop_level++;
but before the line:
  record_unwind_protect (recursive_edit_unwind, buffer);
which registers the code that does the corresponding:
  command_loop_level--;

So the user will be left with every indication that they're in a
recursive edit, except that when they try to use C-M-c it will give them
a cryptic error like "No catch for tag: exit, nil" in the status area
instead of zapping those pesky square brackets.

Here's a patch against master to fix that:
diff --git a/src/keyboard.c b/src/keyboard.c
index d52483e..a5a9ad9 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -825,22 +825,25 @@ This function is called by the editor initialization to begin editing.  */)
   if (input_blocked_p ())
     return Qnil;
 
-  command_loop_level++;
-  update_mode_lines = 17;
-
-  if (command_loop_level
+  if (command_loop_level >= 0
       && current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
     buffer = Fcurrent_buffer ();
   else
     buffer = Qnil;
 
+  /* Don't do anything interesting between the increment and the
+     record_unwind_protect!  Otherwise, we could get distracted and
+     never decrement the counter again.  */
+  command_loop_level++;
+  update_mode_lines = 17;
+  record_unwind_protect (recursive_edit_unwind, buffer);
+
   /* If we leave recursive_edit_1 below with a `throw' for instance,
      like it is done in the splash screen display, we have to
      make sure that we restore single_kboard as command_loop_1
      would have done if it were left normally.  */
   if (command_loop_level > 0)
     temporarily_switch_to_single_kboard (SELECTED_FRAME ());
-  record_unwind_protect (recursive_edit_unwind, buffer);
 
   recursive_edit_1 ();
   return unbind_to (count, Qnil);

In GNU Emacs 24.3.1 (i486-pc-linux-gnu, X toolkit, Xaw3d scroll bars)
 of 2013-12-22 on binet, modified by Debian
Windowing system distributor `Colin Harrison', version 11.0.60900031
System Description:	Debian GNU/Linux testing (jessie)

Configured using:
 `configure '--build' 'i486-linux-gnu' '--build' 'i486-linux-gnu'
 '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib'
 '--localstatedir=/var/lib' '--infodir=/usr/share/info'
 '--mandir=/usr/share/man' '--with-pop=yes'
 '--enable-locallisppath=/etc/emacs24:/etc/emacs:/usr/local/share/emacs/24.3/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/24.3/site-lisp:/usr/share/emacs/site-lisp'
 '--with-crt-dir=/usr/lib/i386-linux-gnu' '--with-x=yes'
 '--with-x-toolkit=lucid' '--with-toolkit-scroll-bars' '--without-gconf'
 '--without-gsettings' 'build_alias=i486-linux-gnu' 'CFLAGS=-g -O2
 -fstack-protector --param=ssp-buffer-size=4 -Wformat
 -Werror=format-security -Wall' 'LDFLAGS=-Wl,-z,relro'
 'CPPFLAGS=-D_FORTIFY_SOURCE=2''

Important settings:
  value of $LC_COLLATE: C
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

-- 
Hi! I'm a .signature virus! Copy me into your ~/.signature to help me spread!