unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#15025: emacs --daemon stuck in infinite loop
@ 2013-08-05 12:36 Dan Nicolaescu
  2013-08-06 23:55 ` Glenn Morris
  0 siblings, 1 reply; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-05 12:36 UTC (permalink / raw)
  To: 15025


This seems to be reproducible. 

emacs compiled with Lucid toolkit

The recipe here uses Xnest because it easy to kill/restart, probably the same
happens if the X session is killed.

Xnest :1&
xterm -display :1&

Now type in the xterm above:
emacs --daemon

In a different xterm type:
emacsclient -t Makefile 
(or any file that exists).
C-z

now while emacsclient is suspended kill Xnest (using the window manager
close button)

Emacs daemon should still survive, but 
emacsclient -t 
cannot connect to it. 

Looking in the debugger, emacs is stuck in an infinite loop in: 

frame.c: next_frame

while (passed < 2)

passed never gets set to more than 1, so the loop never ends.

What is the intention of that code? 






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-05 12:36 bug#15025: emacs --daemon stuck in infinite loop Dan Nicolaescu
@ 2013-08-06 23:55 ` Glenn Morris
  2013-08-07  2:13   ` Dmitry Antipov
  0 siblings, 1 reply; 17+ messages in thread
From: Glenn Morris @ 2013-08-06 23:55 UTC (permalink / raw)
  To: 15025, Dmitry Antipov; +Cc: Dan Nicolaescu

Dan Nicolaescu wrote:

> This seems to be reproducible. 
>
> emacs compiled with Lucid toolkit
>
> The recipe here uses Xnest because it easy to kill/restart, probably the same
> happens if the X session is killed.
>
> Xnest :1&
> xterm -display :1&
>
> Now type in the xterm above:
> emacs --daemon
>
> In a different xterm type:
> emacsclient -t Makefile 
> (or any file that exists).
> C-z
>
> now while emacsclient is suspended kill Xnest (using the window manager
> close button)
>
> Emacs daemon should still survive, but 
> emacsclient -t 
> cannot connect to it. 
>
> Looking in the debugger, emacs is stuck in an infinite loop in: 
>
> frame.c: next_frame
>
> while (passed < 2)
>
> passed never gets set to more than 1, so the loop never ends.
>
> What is the intention of that code? 

It seems this was introduced in
http://lists.gnu.org/archive/html/emacs-diffs/2012-12/msg00093.html

Dmitry, please could you take a look?





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-06 23:55 ` Glenn Morris
@ 2013-08-07  2:13   ` Dmitry Antipov
  2013-08-09  1:23     ` Dan Nicolaescu
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-07  2:13 UTC (permalink / raw)
  To: 15025; +Cc: Dan Nicolaescu

On 08/07/2013 03:55 AM, Glenn Morris wrote:

> Dan Nicolaescu wrote:
>
>> This seems to be reproducible.
>>
>> emacs compiled with Lucid toolkit
>>
>> The recipe here uses Xnest because it easy to kill/restart, probably the same
>> happens if the X session is killed.
>>
>> Xnest :1&
>> xterm -display :1&
>>
>> Now type in the xterm above:
>> emacs --daemon
>>
>> In a different xterm type:
>> emacsclient -t Makefile
>> (or any file that exists).
>> C-z

Should I run "different xterm" connected to base (:0) server or nested (:1)?

Anyway, I can't reproduce it now. Could you please try to run Emacs daemon with -Q?

Dmitry






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-07  2:13   ` Dmitry Antipov
@ 2013-08-09  1:23     ` Dan Nicolaescu
  2013-08-09  2:34       ` Dmitry Antipov
  0 siblings, 1 reply; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-09  1:23 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: 15025

Dmitry Antipov <dmantipov@yandex.ru> writes:

> On 08/07/2013 03:55 AM, Glenn Morris wrote:
>
>> Dan Nicolaescu wrote:
>>
>>> This seems to be reproducible.
>>>
>>> emacs compiled with Lucid toolkit
>>>
>>> The recipe here uses Xnest because it easy to kill/restart, probably the same
>>> happens if the X session is killed.
>>>
>>> Xnest :1&
>>> xterm -display :1&
>>>
>>> Now type in the xterm above:
>>> emacs --daemon
>>>
>>> In a different xterm type:
>>> emacsclient -t Makefile
>>> (or any file that exists).
>>> C-z
>
> Should I run "different xterm" connected to base (:0) server or nested (:1)?

one connected to base.

> Anyway, I can't reproduce it now. Could you please try to run Emacs daemon with -Q?

I rebuilt my emacs, and I can reproduce it anymore.  I do see the
problem from time to time on my work machine, but I cannot reproduce it
reliably.

What should I look for when that happens?  
next_frame has that loop "while (passed < 2)" where emacs gets stuck,
but prev_frame does not.  Any idea what can it make it get stuck there?

I run into another problem when trying to reproduce this:

Xnest :1&
xterm -display :1&

Now type in the xterm above:
emacs -Q --daemon

In a different xterm in the default display (not in Xnest) type:
emacsclient -t Makefile
(or any file that exists).
M-x
C-z

(suspend while in minibuffer)

kill Xnest

go to a different xterm and type
emacsclient -t FOO 

where FOO is a file that exists.  This will display "Makefile", not
"FOO" 

      --dan





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09  1:23     ` Dan Nicolaescu
@ 2013-08-09  2:34       ` Dmitry Antipov
  2013-08-09  9:12         ` martin rudalics
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-09  2:34 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: 15025

On 08/09/2013 05:23 AM, Dan Nicolaescu wrote:

> What should I look for when that happens?
> next_frame has that loop "while (passed < 2)" where emacs gets stuck,
> but prev_frame does not.  Any idea what can it make it get stuck there?

Hm... strange values (dead frame?) in Vframe_list may be a reason.

Next time when it's get stuck, attach gdb and examine:
1) `frame' arg of next_frame;
2) each entry in Vframe_list, like this:

(gdb) call debug_print (Vframe_list)
(#<frame emacs@localhost 0x102d390>)
(gdb) p *(struct frame *)0x102d390
$1 = {header = {size = 4611686018477891605}, name = {i = 12705553}, icon_name = {i = 10920482}, title = {i = 10920482},
   focus_frame = {i = 10920482}, root_window = {i = 16966565}, selected_window = {i = 16966565}, minibuffer_window = {i = 16966997},
   param_alist = {i = 19029702}, scroll_bars = {i = 17338645}, condemned_scroll_bars = {i = 10920482}, menu_bar_items = {i =
     17188581}, face_alist = {i = 19032150}, menu_bar_vector = {i = 42561837}, buffer_predicate = {i = 10920482}, buffer_list = {i =
     19028102}, buried_buffer_list = {i = 10920482}, tool_bar_window = {i = 10920482}, tool_bar_items = {i = 14190525},
   tool_bar_position = {i = 10970402}, desired_tool_bar_string = {i = 10920482}, current_tool_bar_string = {i = 10920482},
   face_cache = 0xc2f6a0, menu_bar_items_used = 0, namebuf = 0x0, current_pool = 0x0, desired_pool = 0x0, desired_matrix = 0x0,
   current_matrix = 0x0, glyphs_initialized_p = 1, resized_p = 0, force_flush_display_p = 0, default_face_done_p = 1,
   already_hscrolled_p = 0, updated_p = 1, minimize_tool_bar_window_p = 0, external_tool_bar = 1, tool_bar_lines = 0,
   n_tool_bar_rows = 0, n_tool_bar_items = 13, decode_mode_spec_buffer = 0xc69d20 "", insert_line_cost = 0x0, delete_line_cost = 0x0,
   insert_n_lines_cost = 0x0, delete_n_lines_cost = 0x0, text_lines = 34, text_cols = 80, total_lines = 0, total_cols = 84,
   new_text_lines = 0, new_text_cols = 0, left_pos = 0, top_pos = 0, pixel_height = 612, pixel_width = 756, x_pixels_diff = 600,
   y_pixels_diff = 85, win_gravity = 1, size_hint_flags = 0, border_width = 0, internal_border_width = 0, column_width = 9,
   line_height = 18, output_method = output_x_window, terminal = 0xf7cab8, output_data = {tty = 0xc1e160, x = 0xc1e160, w32 =
     0xc1e160, ns = 0xc1e160, nothing = 12706144}, font_driver_list = 0x136d520, font_data_list = 0xc7c1c0, fringe_cols = 2,
   left_fringe_width = 9, right_fringe_width = 9, want_fullscreen = FULLSCREEN_NONE, menu_bar_lines = 0, external_menu_bar = 1,
   visible = 1, iconified = 0, garbaged = 0, has_minibuffer = 1, wants_modeline = 1, auto_raise = 0, auto_lower = 0, no_split = 0,
   explicit_name = 0, window_sizes_changed = 0, mouse_moved = 0, pointer_invisible = 0, vertical_scroll_bar_type =
     vertical_scroll_bar_right, desired_cursor = FILLED_BOX_CURSOR, cursor_width = 1, blink_off_cursor = DEFAULT_CURSOR,
   blink_off_cursor_width = 0, config_scroll_bar_width = 16, config_scroll_bar_cols = 2, scroll_bar_actual_width = 18,
   cost_calculation_baud_rate = 19200, alpha = {-1, -1}, gamma = 0, extra_line_spacing = 0, background_pixel = 16777215,
   foreground_pixel = 0}

In particular, if you find the frame with zero f->terminal pointer,
we have dead frames in the game, which is definitely wrong.

Dmitry






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09  2:34       ` Dmitry Antipov
@ 2013-08-09  9:12         ` martin rudalics
  2013-08-09 13:25           ` Dan Nicolaescu
  0 siblings, 1 reply; 17+ messages in thread
From: martin rudalics @ 2013-08-09  9:12 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: Dan Nicolaescu, 15025

 >> next_frame has that loop "while (passed < 2)" where emacs gets stuck,
 >> but prev_frame does not.  Any idea what can it make it get stuck there?
 >
 > Hm... strange values (dead frame?) in Vframe_list may be a reason.

IIUC failing to increment passed can happen only if the frame next_frame
got called with is not on Vframe_list.  We could try asserting that it is.

martin





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09  9:12         ` martin rudalics
@ 2013-08-09 13:25           ` Dan Nicolaescu
  2013-08-09 15:00             ` Dmitry Antipov
  2013-08-09 17:09             ` martin rudalics
  0 siblings, 2 replies; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-09 13:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: Dmitry Antipov, 15025

martin rudalics <rudalics@gmx.at> writes:

>>> next_frame has that loop "while (passed < 2)" where emacs gets stuck,
>>> but prev_frame does not.  Any idea what can it make it get stuck there?
>>
>> Hm... strange values (dead frame?) in Vframe_list may be a reason.
>
> IIUC failing to increment passed can happen only if the frame next_frame
> got called with is not on Vframe_list.  We could try asserting that it is.

That gives the idea of killing multiple emacsclients at the same time...

This looks reproducible:

Xnest :1
xterm -display :1
in that xterm:
emacs -Q --deamon

from the :0 display create 2 more xterms in Xnest:
xterm -display :1
xterm -display :1

and in each of the do 
emacsclient -t 
C-z


in another xterm on :0 do:
emacsclient -t 
C-z

at this point we should have 3 suspended emacsclients, 2 in Xnest, one
in the main display.

Kill Xnest

Now emacs is stuck. VframeList looks like it's empty.





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 13:25           ` Dan Nicolaescu
@ 2013-08-09 15:00             ` Dmitry Antipov
  2013-08-09 19:14               ` Dan Nicolaescu
  2013-08-09 17:09             ` martin rudalics
  1 sibling, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-09 15:00 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: 15025

On 08/09/2013 05:25 PM, Dan Nicolaescu wrote:

> Now emacs is stuck. VframeList looks like it's empty.

...and you should hit `eassert (CONSP (Vframe_list))' in next_frame, but...
do you have ENABLE_CHECKING turned on? (Hunting for a bug without it
is just a waste of time).

Dmitry






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 13:25           ` Dan Nicolaescu
  2013-08-09 15:00             ` Dmitry Antipov
@ 2013-08-09 17:09             ` martin rudalics
  1 sibling, 0 replies; 17+ messages in thread
From: martin rudalics @ 2013-08-09 17:09 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: Dmitry Antipov, 15025

> Now emacs is stuck. VframeList looks like it's empty.

So is it empty?

maartin






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 15:00             ` Dmitry Antipov
@ 2013-08-09 19:14               ` Dan Nicolaescu
  2013-08-09 20:34                 ` martin rudalics
  0 siblings, 1 reply; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-09 19:14 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: 15025

Dmitry Antipov <dmantipov@yandex.ru> writes:

> On 08/09/2013 05:25 PM, Dan Nicolaescu wrote:
>
>> Now emacs is stuck. VframeList looks like it's empty.
>
> ...and you should hit `eassert (CONSP (Vframe_list))' in next_frame, but...
> do you have ENABLE_CHECKING turned on? (Hunting for a bug without it
> is just a waste of time).


It does not trigger that assert.

Vframe_list is:

(gdb) call debug_print(Vframe_list)
(gdb)


The backtrace is: 

(gdb) xbacktrace 
"delete-frame" (0x82f2d508)
"server-delete-client" (0x82f2da00)
"server-sentinel" (0x82f2ded8)

(gdb) bt
#0  next_frame (frame=0x1263165, minibuf=0xd47212)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/frame.c:1016
#1  0x0000000000421e14 in delete_frame (frame=0x1263165, force=0xd18092)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/frame.c:1216
#2  0x000000000042289a in Fdelete_frame (frame=0x1263165, force=0xd18092)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/frame.c:1455
#3  0x00000000005dfc9e in Ffuncall (nargs=0x2, args=0x7fff82f2d500)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2819
#4  0x0000000000628239 in exec_byte_code (bytestr=0x103bf01, vector=0x12c1925, 
    maxdepth=0x38, args_template=0x804, nargs=0x1, args=0x7fff82f2da08)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/bytecode.c:905
#5  0x00000000005e0483 in funcall_lambda (fun=0x11d3e3d, nargs=0x1, 
    arg_vector=0x7fff82f2da00)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2984
#6  0x00000000005dfe60 in Ffuncall (nargs=0x2, args=0x7fff82f2d9f8)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2865
#7  0x0000000000628239 in exec_byte_code (bytestr=0x113dc31, vector=0x128c3f5, 
    maxdepth=0x28, args_template=0x808, nargs=0x2, args=0x7fff82f2dee8)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/bytecode.c:905
#8  0x00000000005e0483 in funcall_lambda (fun=0x11ef1e5, nargs=0x2, 
    arg_vector=0x7fff82f2ded8)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2984
#9  0x00000000005dfe60 in Ffuncall (nargs=0x3, args=0x7fff82f2ded0)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2865
#10 0x00000000005def01 in Fapply (nargs=0x2, args=0x7fff82f2dfa0)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2355
#11 0x00000000005df58d in apply1 (fn=0x300b912, arg=0xec2596)
    at /fac2/vol6/software/dann/hack/emacs/emacs-writable/trunk/src/eval.c:2589





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 19:14               ` Dan Nicolaescu
@ 2013-08-09 20:34                 ` martin rudalics
  2013-08-09 21:54                   ` Dan Nicolaescu
  0 siblings, 1 reply; 17+ messages in thread
From: martin rudalics @ 2013-08-09 20:34 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: Dmitry Antipov, 15025

> It does not trigger that assert.

So put in an assert that the argument frame of next_frame is
on Vframe_list.

martin






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 20:34                 ` martin rudalics
@ 2013-08-09 21:54                   ` Dan Nicolaescu
  2013-08-12  8:10                     ` Dmitry Antipov
  0 siblings, 1 reply; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-09 21:54 UTC (permalink / raw)
  To: martin rudalics; +Cc: Dmitry Antipov, 15025

martin rudalics <rudalics@gmx.at> writes:

>> It does not trigger that assert.
>
> So put in an assert that the argument frame of next_frame is
> on Vframe_list.

Unfortunately I won't have time to debug this any time soon.
But the recipe I gave shows the problem every time, so hopefully someone
can track down the problem.







^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-09 21:54                   ` Dan Nicolaescu
@ 2013-08-12  8:10                     ` Dmitry Antipov
  2013-08-13 14:41                       ` Dan Nicolaescu
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-12  8:10 UTC (permalink / raw)
  To: 15025; +Cc: Dan Nicolaescu, Paul Eggert

On 08/10/2013 01:54 AM, Dan Nicolaescu wrote:

> Unfortunately I won't have time to debug this any time soon.
> But the recipe I gave shows the problem every time, so hopefully someone
> can track down the problem.

Finally I got it reproduced. Very nasty and long-standing issue (I'm pretty
sure that it was there before r111121).

The problem is that candidate_frame looks for 1) frames which shares the
keyboard for graphical frames or 2) frames which share the TTY for termcap
frames. But with Dan's example, we have:

(gdb) p XFRAME (frame)
$20 = (struct frame *) 0x108c6e0  ; argument of `next_frame'

And in Vframe_list:

(gdb) p XFRAME (XCAR (Vframe_list))
$27 = (struct frame *) 0x10756e0
(gdb) p XFRAME (XCAR (Vframe_list))->terminal
$28 = (struct terminal *) 0x1075570                         ; TTY /dev/pts/X
(gdb) p XFRAME (XCAR (Vframe_list))->output_method
$29 = output_termcap

(gdb) p XFRAME (XCAR (XCDR (Vframe_list)))
$30 = (struct frame *) 0x108c6e0
(gdb) p XFRAME (XCAR (XCDR (Vframe_list)))->terminal
$31 = (struct terminal *) 0xbeba70                          ; TTY /dev/pts/Y
(gdb) p XFRAME (XCAR (XCDR (Vframe_list)))->output_method
$32 = output_termcap

Two TTY frames on a different TTYs! So, candidate_frame always returns Qnil.

But the problem is much more interesting than redesign this:

  if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f)
        && FRAME_KBOARD (c) == FRAME_KBOARD (f))
       || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f)
	  && FRAME_TTY (c) == FRAME_TTY (f)))

IIUC, TTY "peers" (which was on xterms connected to :1) of Emacs frames becomes
invalid when Xnest dies. I suspect that we should have a method to handle such
a "TTY disconnect", but currently I have no ideas how to implement this :-(.

Dmitry





^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-12  8:10                     ` Dmitry Antipov
@ 2013-08-13 14:41                       ` Dan Nicolaescu
  2013-08-14 17:43                         ` Dmitry Antipov
  2013-08-15 15:40                         ` Dmitry Antipov
  0 siblings, 2 replies; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-13 14:41 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: Paul Eggert, 15025

Dmitry Antipov <dmantipov@yandex.ru> writes:

> On 08/10/2013 01:54 AM, Dan Nicolaescu wrote:
>
>> Unfortunately I won't have time to debug this any time soon.
>> But the recipe I gave shows the problem every time, so hopefully someone
>> can track down the problem.
>
> Finally I got it reproduced. Very nasty and long-standing issue (I'm pretty
> sure that it was there before r111121).
>
> The problem is that candidate_frame looks for 1) frames which shares the
> keyboard for graphical frames or 2) frames which share the TTY for termcap
> frames. But with Dan's example, we have:
>
> (gdb) p XFRAME (frame)
> $20 = (struct frame *) 0x108c6e0  ; argument of `next_frame'
>
> And in Vframe_list:
>
> (gdb) p XFRAME (XCAR (Vframe_list))
> $27 = (struct frame *) 0x10756e0
> (gdb) p XFRAME (XCAR (Vframe_list))->terminal
> $28 = (struct terminal *) 0x1075570                         ; TTY /dev/pts/X
> (gdb) p XFRAME (XCAR (Vframe_list))->output_method
> $29 = output_termcap
>
> (gdb) p XFRAME (XCAR (XCDR (Vframe_list)))
> $30 = (struct frame *) 0x108c6e0
> (gdb) p XFRAME (XCAR (XCDR (Vframe_list)))->terminal
> $31 = (struct terminal *) 0xbeba70                          ; TTY /dev/pts/Y
> (gdb) p XFRAME (XCAR (XCDR (Vframe_list)))->output_method
> $32 = output_termcap
>
> Two TTY frames on a different TTYs! So, candidate_frame always returns Qnil.

Does this happen because two TTY frames got killed at the same time
(because the xterm they were running on was killed)? 

Does emacs think that those frames are still alive? 

What is the goal when looking for frames that share the TTY ? 

[I don't know what the code in question is trying to do...]


> But the problem is much more interesting than redesign this:
>
>  if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f)
>        && FRAME_KBOARD (c) == FRAME_KBOARD (f))
>       || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f)
> 	  && FRAME_TTY (c) == FRAME_TTY (f)))
>
> IIUC, TTY "peers" (which was on xterms connected to :1) of Emacs frames becomes
> invalid when Xnest dies. I suspect that we should have a method to handle such
> a "TTY disconnect", but currently I have no ideas how to implement this :-(.






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-13 14:41                       ` Dan Nicolaescu
@ 2013-08-14 17:43                         ` Dmitry Antipov
  2013-08-15 15:40                         ` Dmitry Antipov
  1 sibling, 0 replies; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-14 17:43 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: Paul Eggert, 15025

[-- Attachment #1: Type: text/plain, Size: 236 bytes --]

Dan,

could you please try this hack? You should see some noise from
lisp/server.el code (because server process doesn't know about
dead terminals), and warnings about frame deletion. But it
shouldn't crash or stuck at least...

Dmitry

[-- Attachment #2: bug15025_hack.patch --]
[-- Type: text/plain, Size: 3914 bytes --]

=== modified file 'src/frame.c'
--- src/frame.c	2013-08-14 16:36:16 +0000
+++ src/frame.c	2013-08-14 17:28:21 +0000
@@ -1199,8 +1199,14 @@
     {
       Lisp_Object tail, frame1;
 
-      /* Look for another visible frame on the same terminal.  */
-      frame1 = next_frame (frame, Qvisible);
+      /* Look for another visible frame on the same terminal.
+	 Do not call next_frame here. FIXME this.  */
+      FOR_EACH_FRAME (tail, frame1)
+	if (!EQ (frame, frame1)
+	    && (FRAME_TERMINAL (XFRAME (frame))
+		== FRAME_TERMINAL (XFRAME (frame1)))
+	    && FRAME_VISIBLE_P (XFRAME (frame1)))
+	  break;
 
       /* If there is none, find *some* other frame.  */
       if (NILP (frame1) || EQ (frame1, frame))

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2013-08-13 08:39:14 +0000
+++ src/keyboard.c	2013-08-14 17:12:39 +0000
@@ -6847,17 +6847,21 @@
                    alone in its group.  */
 		terminate_due_to_signal (SIGHUP, 10);
 
-              /* XXX Is calling delete_terminal safe here?  It calls delete_frame.  */
-	      {
-		Lisp_Object tmp;
-		XSETTERMINAL (tmp, t);
-		Fdelete_terminal (tmp, Qnoelisp);
-	      }
+	      /* This terminal is now dead.  */
+	      t->dead = 1;
             }
 
           if (hold_quit.kind != NO_EVENT)
             kbd_buffer_store_event (&hold_quit);
         }
+      else
+	{
+	  /* If read_socket_hook is NULL, T is suspended.  But T may be
+	     dead, see http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025.  */
+	  if (t->type == output_termcap
+	      && !check_tty_alive (t->display_info.tty->name))
+	    t->dead = 1;
+	}
 
       t = next;
     }
@@ -7079,6 +7083,7 @@
 {
   pending_signals = 0;
   handle_async_input ();
+  drop_dead_terminals ();
   do_pending_atimers ();
 }
 

=== modified file 'src/lisp.h'
--- src/lisp.h	2013-08-14 16:36:16 +0000
+++ src/lisp.h	2013-08-14 17:14:11 +0000
@@ -4094,6 +4094,7 @@
 extern void sys_subshell (void);
 extern void sys_suspend (void);
 extern void discard_tty_input (void);
+extern bool check_tty_alive (char *);
 extern void block_tty_out_signal (void);
 extern void unblock_tty_out_signal (void);
 extern void init_sys_modes (struct tty_display_info *);

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2013-08-09 12:25:34 +0000
+++ src/sysdep.c	2013-08-14 17:13:48 +0000
@@ -734,6 +734,15 @@
 #endif
 }
 
+/* This works on Linux, but no ideas for others.  */
+
+bool
+check_tty_alive (char *tty)
+{
+  int fd = emacs_open (tty, O_RDWR | O_NONBLOCK, 0);
+  return fd > 0 ? (emacs_close (fd), 1) : 0;
+}
+
 /* Safely set a controlling terminal FD's process group to PGID.
    If we are not in the foreground already, POSIX requires tcsetpgrp
    to deliver a SIGTTOU signal, which would stop us.  This is an

=== modified file 'src/termhooks.h'
--- src/termhooks.h	2013-07-16 11:41:06 +0000
+++ src/termhooks.h	2013-08-14 17:04:49 +0000
@@ -362,6 +362,9 @@
   /* Chain of all terminal devices. */
   struct terminal *next_terminal;
 
+  /* Nonzero if this terminal is really dead.  */
+  unsigned dead : 1;
+
   /* Unique id for this terminal device. */
   int id;
 
@@ -648,6 +651,7 @@
 extern struct terminal *get_terminal (Lisp_Object terminal, bool);
 extern struct terminal *create_terminal (void);
 extern void delete_terminal (struct terminal *);
+extern void drop_dead_terminals (void);
 
 /* The initial terminal device, created by initial_term_init.  */
 extern struct terminal *initial_terminal;

=== modified file 'src/terminal.c'
--- src/terminal.c	2013-07-31 06:05:05 +0000
+++ src/terminal.c	2013-08-14 17:36:30 +0000
@@ -537,6 +537,24 @@
 }
 
 void
+drop_dead_terminals (void)
+{
+  struct terminal *t, *next;
+
+  for (t = terminal_list; t; t = next)
+    {
+      next = t->next_terminal;
+      if (t->dead)
+	{
+	  if (t->delete_terminal_hook)
+	    (*t->delete_terminal_hook) (t);
+	  else
+	    delete_terminal (t);
+	}
+    }
+}
+
+void
 syms_of_terminal (void)
 {
 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-13 14:41                       ` Dan Nicolaescu
  2013-08-14 17:43                         ` Dmitry Antipov
@ 2013-08-15 15:40                         ` Dmitry Antipov
  2013-08-16 18:36                           ` Dan Nicolaescu
  1 sibling, 1 reply; 17+ messages in thread
From: Dmitry Antipov @ 2013-08-15 15:40 UTC (permalink / raw)
  To: 15025; +Cc: Dan Nicolaescu

Hopefully should be fixed in r113891.

Dmitry






^ permalink raw reply	[flat|nested] 17+ messages in thread

* bug#15025: emacs --daemon stuck in infinite loop
  2013-08-15 15:40                         ` Dmitry Antipov
@ 2013-08-16 18:36                           ` Dan Nicolaescu
  0 siblings, 0 replies; 17+ messages in thread
From: Dan Nicolaescu @ 2013-08-16 18:36 UTC (permalink / raw)
  To: Dmitry Antipov; +Cc: 15025-done

Dmitry Antipov <dmantipov@yandex.ru> writes:

> Hopefully should be fixed in r113891.


Thanks, it looks like the infinite loop is gone now.

        --dan





^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-08-16 18:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-05 12:36 bug#15025: emacs --daemon stuck in infinite loop Dan Nicolaescu
2013-08-06 23:55 ` Glenn Morris
2013-08-07  2:13   ` Dmitry Antipov
2013-08-09  1:23     ` Dan Nicolaescu
2013-08-09  2:34       ` Dmitry Antipov
2013-08-09  9:12         ` martin rudalics
2013-08-09 13:25           ` Dan Nicolaescu
2013-08-09 15:00             ` Dmitry Antipov
2013-08-09 19:14               ` Dan Nicolaescu
2013-08-09 20:34                 ` martin rudalics
2013-08-09 21:54                   ` Dan Nicolaescu
2013-08-12  8:10                     ` Dmitry Antipov
2013-08-13 14:41                       ` Dan Nicolaescu
2013-08-14 17:43                         ` Dmitry Antipov
2013-08-15 15:40                         ` Dmitry Antipov
2013-08-16 18:36                           ` Dan Nicolaescu
2013-08-09 17:09             ` martin rudalics

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).