Commit 256c9c3a authored by Karoly Lorentey's avatar Karoly Lorentey

Fix crash after y-or-n-p prompt triggered by emacsclient. (Reported by Han...

Fix crash after y-or-n-p prompt triggered by emacsclient. (Reported by Han Boetes, analysis by Kalle Olavi Niemitalo.)

* src/keyboard.c (temporarily_switch_to_single_kboard)
  (record_single_kboard_state, restore_kboard_configuration):  New functions.
  (timer_check): Use record_single_kboard_state instead of
  naive single_kboard state management.

* src/fns.c: Include termhooks.h.
  (Fy_or_n_p): Use temporarily_switch_to_single_kboard to prevent crashes
  caused by bogus longjmps in read_char.

* src/callint.c (Fcall_interactively): Use
  temporarily_switch_to_single_kboard instead of single_kboard_state.
  Make sure it is correctly unwinded.

* src/keyboard.c (recursive_edit_unwind): Remove single_kboard stuff.
  (Frecursive_edit): Use temporarily_switch_to_single_kboard for
  single_kboard state management.

* src/minibuf.c (read_minibuf): Use temporarily_switch_to_single_kboard
  instead of simply calling single_kboard_state.

* src/keyboard.c (push_device_kboard): Remove function.
  (push_kboard): New function.
  (push_frame_kboard): Use it.
  (pop_frame_kboard): Rename to pop_kboard.

* src/xdisp.c (display_mode_line, Fformat_mode_line): Update uses.

* src/data.c: Include termhooks.h.
  (Fterminal_local_value, Fset_terminal_local_value): Update.

* src/Makefile.in (data.o, fns.o): Add termhooks.h dependency.

* src/keyboard.h (push_device_kboard, pop_frame_kboard): Remove declarations.
  (push_kboard, pop_kboard, temporarily_switch_to_single_kboard)
  (record_single_kboard_state): New declarations.


git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-414
parent ee0bcfbc
......@@ -31,27 +31,28 @@ The following is a (sadly incomplete) list of people who have
contributed to the project by testing, submitting patches, bug
reports, and suggestions. Thanks!
ARISAWA Akihiro <ari at mbf dot ocn dot ne dot jp>
Vincent Bernat <bernat at luffy dot cx>
Han Boetes <han at mijncomputer dot nl>
Robert J. Chassell <bob at rattlesnake dot com>
Romain Francoise <romain at orebokech dot com>
Ami Fischman <ami at fischman dot org>
Friedrich Delgado Friedrichs <friedel at nomaden dot org>
IRIE Tetsuya <irie at t dot email dot ne dot jp>
Yoshiaki Kasahara <kasahara at nc dot kyushu-u dot ac dot jp>
Bas Kok <nekkobassu at yahoo dot com>
Jurej Kubelka <Juraj dot Kubelka at email dot cz>
David Lichteblau <david at lichteblau dot com>
Xavier Mallard <zedek at gnu-rox dot org>
Istvan Marko <mi-mtty at kismala dot com>
Ted Morse <morse at ciholas dot com>
Dan Nicolaescu <dann at ics dot uci dot edu>
Gergely Nagy <algernon at debian dot org>
Mark Plaksin <happy at mcplaksin dot org>
Francisco Borges <borges at let dot rug dot nl>
Frank Ruell <stoerte at dreamwarrior dot net>
Dan Waber <dwaber at logolalia dot com>
ARISAWA Akihiro <ari@mbf.ocn.ne.jp>
Vincent Bernat <bernat@luffy.cx>
Han Boetes <han@mijncomputer.nl>
Robert J. Chassell <bob@rattlesnake.com>
Romain Francoise <romain@orebokech.com>
Ami Fischman <ami@fischman.org>
Friedrich Delgado Friedrichs <friedel@nomaden.org>
IRIE Tetsuya <irie@t.email.ne.jp>
Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp>
Bas Kok <nekkobassu@yahoo.com>
Jurej Kubelka <Juraj.Kubelka@email.cz>
David Lichteblau <david@lichteblau.com>
Xavier Mallard <zedek@gnu-rox.org>
Istvan Marko <mi-mtty@kismala.com>
Ted Morse <morse@ciholas.com>
Gergely Nagy <algernon@debian.org>
Dan Nicolaescu <dann@ics.uci.edu>
Kalle Olavi Niemitalo <kon@iki.fi>
Mark Plaksin <happy@mcplaksin.org>
Francisco Borges <borges@let.rug.nl>
Frank Ruell <stoerte@dreamwarrior.net>
Dan Waber <dwaber@logolalia.com>
and many others.
Richard Stallman was kind enough to review an earlier version of my
......@@ -387,17 +388,8 @@ is probably not very interesting for anyone else.)
THINGS TO DO
------------
** This long-standing bug (first reported by Han Boetes) seems to come
and go all the time. It is time to track it down and fix it.
emacs
M-x server-start
# From another xterm:
emacsclient -e '(y-or-n-p "Do you want me to crash? ")'
# Notice how the answer ends up in the *scratch* buffer
M-x garbage-collect
SIGSEGV
** Report GTK multi-display problems to GTK maintainers. For extra
credit, fix them.
** frames-on-display-list should also accept frames.
......@@ -1239,5 +1231,19 @@ DIARY OF CHANGES
(I think patch-370 fixed this.)
-- This long-standing bug (first reported by Han Boetes) seems to come
and go all the time. It is time to track it down and fix it.
emacs
M-x server-start
# From another xterm:
emacsclient -e '(y-or-n-p "Do you want me to crash? ")'
# Notice how the answer ends up in the *scratch* buffer
M-x garbage-collect
SIGSEGV
(Fixed in patch-414 after detailed analysis by Kalle Olavi Niemitalo.)
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
......@@ -1213,13 +1213,13 @@ alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h key
blockinput.h atimer.h systime.h charset.h dispextern.h $(config_h) $(INTERVAL_SRC)
bytecode.o: bytecode.c buffer.h syntax.h charset.h window.h dispextern.h \
frame.h xterm.h $(config_h)
data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h $(config_h)
data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h termhooks.h $(config_h)
eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
dispextern.h $(config_h)
floatfns.o: floatfns.c $(config_h)
fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
keymap.h frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h \
blockinput.h xterm.h
blockinput.h xterm.h termhooks.h
print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \
$(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h \
termchar.h
......
......@@ -408,8 +408,8 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */)
real_this_command= save_real_this_command;
current_kboard->Vlast_command = save_last_command;
single_kboard_state ();
return apply1 (function, specs);
temporarily_switch_to_single_kboard (NULL);
return unbind_to (speccount, apply1 (function, specs));
}
/* Here if function specifies a string to control parsing the defaults */
......@@ -875,7 +875,7 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */)
real_this_command= save_real_this_command;
current_kboard->Vlast_command = save_last_command;
single_kboard_state ();
temporarily_switch_to_single_kboard (NULL);
{
Lisp_Object val;
......
......@@ -30,6 +30,7 @@ Boston, MA 02110-1301, USA. */
#include "keyboard.h"
#include "frame.h"
#include "syssignal.h"
#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */
#ifdef STDC_HEADERS
#include <float.h>
......@@ -1891,9 +1892,9 @@ selected frame's display device). */)
{
Lisp_Object result;
struct device *d = get_device (device, 1);
push_device_kboard (d);
push_kboard (d->kboard);
result = Fsymbol_value (symbol);
pop_frame_kboard ();
pop_kboard ();
return result;
}
......@@ -1911,9 +1912,9 @@ selected frame's display device). */)
{
Lisp_Object result;
struct device *d = get_device (device, 1);
push_device_kboard (d);
push_kboard (d->kboard);
result = Fset (symbol, value);
pop_frame_kboard ();
pop_kboard ();
return result;
}
......
......@@ -48,6 +48,7 @@ Boston, MA 02110-1301, USA. */
#include "frame.h"
#include "window.h"
#include "blockinput.h"
#include "termhooks.h" /* For display->kboard reference in terminal-local-value. */
#if defined (HAVE_MENUS) && defined (HAVE_X_WINDOWS)
#include "xterm.h"
#endif
......@@ -3307,7 +3308,9 @@ is nil and `use-dialog-box' is non-nil. */)
Fraise_frame (mini_frame);
}
temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ()));
obj = read_filtered_event (1, 0, 0, 0);
cursor_in_echo_area = 0;
/* If we need to quit, quit with cursor_in_echo_area = 0. */
QUIT;
......
......@@ -1034,24 +1034,19 @@ This function is called by the editor initialization to begin editing. */)
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. */
record_unwind_protect (recursive_edit_unwind,
Fcons (buffer, single_kboard ? Qt : Qnil));
temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ()));
record_unwind_protect (recursive_edit_unwind, buffer);
recursive_edit_1 ();
return unbind_to (count, Qnil);
}
Lisp_Object
recursive_edit_unwind (info)
Lisp_Object info;
recursive_edit_unwind (buffer)
Lisp_Object buffer;
{
if (BUFFERP (XCAR (info)))
Fset_buffer (XCAR (info));
if (NILP (XCDR (info)))
any_kboard_state ();
else
single_kboard_state ();
if (BUFFERP (buffer))
Fset_buffer (buffer);
command_loop_level--;
update_mode_lines = 1;
......@@ -1116,8 +1111,8 @@ struct kboard_stack
static struct kboard_stack *kboard_stack;
void
push_device_kboard (d)
struct device *d;
push_kboard (k)
struct kboard *k;
{
#ifdef MULTI_KBOARD
struct kboard_stack *p
......@@ -1127,7 +1122,7 @@ push_device_kboard (d)
p->kboard = current_kboard;
kboard_stack = p;
current_kboard = d->kboard;
current_kboard = k;
#endif
}
......@@ -1135,20 +1130,11 @@ void
push_frame_kboard (f)
FRAME_PTR f;
{
#ifdef MULTI_KBOARD
struct kboard_stack *p
= (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack));
p->next = kboard_stack;
p->kboard = current_kboard;
kboard_stack = p;
current_kboard = FRAME_KBOARD (f);
#endif
push_kboard (f->device->kboard);
}
void
pop_frame_kboard ()
pop_kboard ()
{
#ifdef MULTI_KBOARD
struct kboard_stack *p = kboard_stack;
......@@ -1157,6 +1143,46 @@ pop_frame_kboard ()
xfree (p);
#endif
}
/* Switch to single_kboard mode. If K is non-nil, set it as the
current keyboard. Use record_unwind_protect to return to the
previous state later. */
void
temporarily_switch_to_single_kboard (k)
struct kboard *k;
{
#ifdef MULTI_KBOARD
int was_locked = single_kboard;
if (k != NULL)
push_kboard (k);
else
push_kboard (current_kboard);
single_kboard_state ();
record_unwind_protect (restore_kboard_configuration,
(was_locked ? Qt : Qnil));
#endif
}
void
record_single_kboard_state ()
{
push_kboard (current_kboard);
record_unwind_protect (restore_kboard_configuration,
(single_kboard ? Qt : Qnil));
}
static Lisp_Object
restore_kboard_configuration (was_locked)
Lisp_Object was_locked;
{
pop_kboard ();
if (NILP (was_locked))
any_kboard_state ();
else
single_kboard_state ();
return Qnil;
}
/* Handle errors that are not handled at inner levels
by printing an error message and returning to the editor command loop. */
......@@ -4472,10 +4498,13 @@ timer_check (do_it_now)
{
if (NILP (vector[0]))
{
int was_locked = single_kboard;
int count = SPECPDL_INDEX ();
Lisp_Object old_deactivate_mark = Vdeactivate_mark;
/* On unbind_to, resume allowing input from any kboard, if that
was true before. */
record_single_kboard_state ();
/* Mark the timer as triggered to prevent problems if the lisp
code fails to reschedule it right. */
vector[0] = Qt;
......@@ -4487,10 +4516,6 @@ timer_check (do_it_now)
timers_run++;
unbind_to (count, Qnil);
/* Resume allowing input from any kboard, if that was true before. */
if (!was_locked)
any_kboard_state ();
/* Since we have handled the event,
we don't need to tell the caller to wake up and do it. */
}
......
......@@ -319,9 +319,11 @@ extern void init_kboard P_ ((KBOARD *));
extern void delete_kboard P_ ((KBOARD *));
extern void single_kboard_state P_ ((void));
extern void not_single_kboard_state P_ ((KBOARD *));
extern void push_device_kboard P_ ((struct device *));
extern void push_kboard P_ ((struct kboard *));
extern void push_frame_kboard P_ ((struct frame *));
extern void pop_frame_kboard P_ ((void));
extern void pop_kboard P_ ((void));
extern void temporarily_switch_to_single_kboard P_ ((struct kboard *));
extern void record_single_kboard_state P_ ((void));
extern void record_asynch_buffer_change P_ ((void));
extern SIGTYPE input_poll_signal P_ ((int));
extern void start_polling P_ ((void));
......
......@@ -467,7 +467,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
specbind (Qminibuffer_default, defalt);
single_kboard_state ();
#ifdef HAVE_X_WINDOWS
if (display_hourglass_p)
cancel_hourglass ();
......@@ -551,6 +550,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
if (minibuffer_auto_raise)
Fraise_frame (mini_frame);
temporarily_switch_to_single_kboard (XFRAME (mini_frame)->device->kboard);
/* We have to do this after saving the window configuration
since that is what restores the current buffer. */
......
......@@ -15888,7 +15888,7 @@ display_mode_line (w, face_id, format)
values. */
push_frame_kboard (it.f);
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
pop_frame_kboard ();
pop_kboard ();
unbind_to (count, Qnil);
......@@ -16551,7 +16551,7 @@ are the selected window and the window's buffer). */)
push_frame_kboard (it.f);
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
pop_frame_kboard ();
pop_kboard ();
if (no_props)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment