emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SIGABRT while stress-testing with gnuclient/gnudoit


From: Alex Schroeder
Subject: Re: SIGABRT while stress-testing with gnuclient/gnudoit
Date: Sat, 04 Jan 2003 01:13:10 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/21.2.92 (i686-pc-linux-gnu)

Richard Stallman <address@hidden> writes:

>     ~% emacs -q
>
>     In the scratch-buffer, evaluate (delete-frame (selected-frame) t)
>     and you will get this:
>
>     Fatal error (6).zsh: abort      emacs -q
>
> When I do this, Emacs exits normally.  command_loop_1 calls
> Fkill_emacs when there are no frames.
>
> I guess the abort just is not happening for me.  Can you investigate
> what leads up to it?

I have no experience debugging Emacs, so I am sending a rather
elaborate log of what I did so that people can point me in the right
directions if I blunder along the way.  :)

If you are just interested in the result, here is the executive
summary from my point of view:  In command_loop_1 there is a test on
lines 1444-1445.

     if (! FRAME_LIVE_P (XFRAME (selected_frame)))
        Fkill_emacs (Qnil);

But at this point, the command has not been evaluated, yet.  So when
we get to line 1644, the function called is eval-last-sexp.  After the
code has been executed, there are no more frames left.  Now emacs
tries to print the result of the eval-last-sexp, and calls prin1 to do
it.  prin1 eventually calls window_loop to figure out where to print
it, and fails to find a using the SELECTED_FRAME macro.  This macro
aborts.

The proposed solution is to just replace the abort call in
SELECTED_FRAME with a call to kill_emacs, just like the code at line
1444 cited above does.  Another option would be to find a place after
functions are called but before results are printed to make this test.
The test at line 1444 comes too early and has no effect (for my
problem, at least).



Anyway, here is the log:

I started emacs -q and gdb, set a breakpoint at command_loop_1, pasted
the line, evaluated (delete-frame (selected-frame) t) using C-x C-e
and emacs aborted before hitting the breakpoint again.  Strange.  (I
must try this again.)

(gdb) bt
#0  0x4030b781 in kill () from /lib/libc.so.6
#1  0x080ce94e in abort () at emacs.c:387
#2  0x08076846 in window_loop (type=GET_BUFFER_WINDOW, obj=1210793848, mini=1, 
    frames=405209228) at window.c:1776
#3  0x08076cd4 in Fget_buffer_window (buffer=1210793848, frame=405209228)
    at window.c:1997
#4  0x080623cf in message_dolog (m=0xbfffef48 "n\306'H|\361\377\277-*\023\bn", 
    nbytes=1, nlflag=0, multibyte=1) at xdisp.c:5783
#5  0x0812f7ba in printchar (ch=110, fun=405209228) at print.c:343
#6  0x08132a2d in print_object (obj=405209180, printcharfun=405209228, 
    escapeflag=1) at print.c:1532
#7  0x08132021 in print (obj=405209180, printcharfun=405209228, escapeflag=1)
    at print.c:1180
#8  0x08130e4a in Fprin1 (object=405209180, printcharfun=405209180)
    at print.c:731
#9  0x08123ced in Ffuncall (nargs=2, args=0xbffff274) at eval.c:2662
#10 0x0814a34c in Fbyte_code (bytestr=941751892, vector=1210187588, 
    maxdepth=10) at bytecode.c:716
#11 0x08124297 in funcall_lambda (fun=1210187312, nargs=1, 
    arg_vector=0xbffff3a8) at eval.c:2851
#12 0x08123e01 in Ffuncall (nargs=2, args=0xbffff3a4) at eval.c:2716
#13 0x0814a34c in Fbyte_code (bytestr=941752452, vector=1210187964, maxdepth=4)
    at bytecode.c:716
#14 0x08124297 in funcall_lambda (fun=1210187868, nargs=1, 
    arg_vector=0xbffff4f8) at eval.c:2851
#15 0x08123e01 in Ffuncall (nargs=2, args=0xbffff4f4) at eval.c:2716
#16 0x081209a9 in Fcall_interactively (function=405517980, 
    record_flag=405209180, keys=1210574296) at callint.c:797
#17 0x080daa6a in Fcommand_execute (cmd=405517980, record_flag=405209180, 
    keys=405209180, special=405209180) at keyboard.c:9232
#18 0x080d1bd0 in command_loop_1 () at keyboard.c:1644
#19 0x08122249 in internal_condition_case (bfun=0x80d1090 <command_loop_1>, 
    handlers=405305524, hfun=0x80d0cd4 <cmd_error>) at eval.c:1267
#20 0x080d0f68 in command_loop_2 () at keyboard.c:1245
#21 0x08121ddd in internal_catch (tag=405267108, 
    func=0x80d0f44 <command_loop_2>, arg=405209180) at eval.c:1030
#22 0x080d0f17 in command_loop () at keyboard.c:1224
#23 0x080d0a91 in recursive_edit_1 () at keyboard.c:950
#24 0x080d0bc0 in Frecursive_edit () at keyboard.c:1006
#25 0x080cfaef in main (argc=2, argv=0xbffffc74, envp=0xbffffc80)
    at emacs.c:1547

So I figured that the evaluation tries to print something, which
fails because there is no frame to print the result.  This seems
validated by the following, which shows that Emacs is trying to prin1
nil -- I assume the return value of the call to delete-frame.

(gdb) up 9
#9  0x08123ced in Ffuncall (nargs=2, args=0xbffff274) at eval.c:2662
2662              val = (*XSUBR (fun)->function) (internal_args[0],
(gdb) p *args
$1 = 405327228
(gdb) pr
prin1
(gdb) p args[1]
$2 = 405209180
(gdb) pr
nil

Nothing strange going on down here, so I thought about verifying your
claim that kill_emacs is called in command_loop_1.

(gdb) up 9
#18 0x080d1bd0 in command_loop_1 () at keyboard.c:1644
1644              Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
(gdb) l
1639    #endif
1640
1641              nonundocount = 0;
1642              if (NILP (current_kboard->Vprefix_arg))
1643                Fundo_boundary ();
1644              Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
1645
1646    #ifdef HAVE_X_WINDOWS
1647              if (display_hourglass_p)
1648                cancel_hourglass ();

Note that the test for frame stuff is much earlier (1444-1445):

      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
        Fkill_emacs (Qnil);

So I am assuming that the delete-frame has not been executed yet.  And
I think I am right:

(gdb) p Vthis_command
$3 = 405517980
(gdb) pr
eval-last-sexp

Therefore either you are wrong, or we are not looking at the same
keyboard.c.  I am using the pretest, that is revision 1.626.4.4.  This
looks correct, because that matches the tag EMACS_PRETEST_21_2_93.

So then I looked at the Changes between 1.626.4.4 and 1.717.  Nothing
seems to suggest itself.

If I am right, and the delete-frame is only executed by the
eval-last-sexp in command_loop_1 at line 1644, then the call to
kill_emacs you describe, which happens at line 1369, cannot be
responsible for the clean exit you describe.

Unless we do not have the same window.c?  Here is the part on #2:

#2  0x08076846 in window_loop (type=GET_BUFFER_WINDOW, obj=1210793848, mini=1, 
    frames=405209228) at window.c:1776
1776        window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
(gdb) l
1771      if (WINDOWP (obj))
1772        window = obj;
1773      else if (f)
1774        window = FRAME_SELECTED_WINDOW (f);
1775      else
1776        window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1777
1778      windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
1779      GCPRO1 (windows);
1780      best_window = Qnil;

I have revision 1.376.4.8, which belongs to EMACS_PRETEST_21_2_93.  So
I have the correct revision.  Looking at the differences between
1.376.4.8 and 1.434 in the area of interest, I see nothing suspicious.

Well, I could look at obj:

(gdb) p obj
$4 = 1210793848
(gdb) pr
#<buffer *Messages*>

This sounds plausible, I guess.

So what is the value of f:

(gdb) p f
$5 = (struct frame *) 0x82b3f80
(gdb) pr
-131383424

This is strange.  If we are in line 1776, then I would have assumed f
to be 0.  I think something got corrupted on the way and set a
breakpoint here, and reran the test.  The new backtrace:

Breakpoint 8, window_loop (type=GET_BUFFER_WINDOW, obj=1210793848, mini=1, 
    frames=405209228) at window.c:1776
1776        window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
(gdb) bt
#0  window_loop (type=GET_BUFFER_WINDOW, obj=1210793848, mini=1, 
    frames=405209228) at window.c:1776
#1  0x08076cd4 in Fget_buffer_window (buffer=1210793848, frame=405209228)
    at window.c:1997
#2  0x080623cf in message_dolog (m=0xbfffef48 "n\306'H|\361\377\277-*\023\bn", 
    nbytes=1, nlflag=0, multibyte=1) at xdisp.c:5783
#3  0x0812f7ba in printchar (ch=110, fun=405209228) at print.c:343
#4  0x08132a2d in print_object (obj=405209180, printcharfun=405209228, 
    escapeflag=1) at print.c:1532
#5  0x08132021 in print (obj=405209180, printcharfun=405209228, escapeflag=1)
    at print.c:1180
#6  0x08130e4a in Fprin1 (object=405209180, printcharfun=405209180)
    at print.c:731
#7  0x08123ced in Ffuncall (nargs=2, args=0xbffff274) at eval.c:2662
#8  0x0814a34c in Fbyte_code (bytestr=941751892, vector=1210187588, 
    maxdepth=10) at bytecode.c:716
#9  0x08124297 in funcall_lambda (fun=1210187312, nargs=1, 
    arg_vector=0xbffff3a8) at eval.c:2851
#10 0x08123e01 in Ffuncall (nargs=2, args=0xbffff3a4) at eval.c:2716
#11 0x0814a34c in Fbyte_code (bytestr=941752452, vector=1210187964, maxdepth=4)
    at bytecode.c:716
#12 0x08124297 in funcall_lambda (fun=1210187868, nargs=1, 
    arg_vector=0xbffff4f8) at eval.c:2851
#13 0x08123e01 in Ffuncall (nargs=2, args=0xbffff4f4) at eval.c:2716
#14 0x081209a9 in Fcall_interactively (function=405517980, 
    record_flag=405209180, keys=1210574296) at callint.c:797
#15 0x080daa6a in Fcommand_execute (cmd=405517980, record_flag=405209180, 
    keys=405209180, special=405209180) at keyboard.c:9232
#16 0x080d1bd0 in command_loop_1 () at keyboard.c:1644
#17 0x08122249 in internal_condition_case (bfun=0x80d1090 <command_loop_1>, 
    handlers=405305524, hfun=0x80d0cd4 <cmd_error>) at eval.c:1267
#18 0x080d0f68 in command_loop_2 () at keyboard.c:1245
#19 0x08121ddd in internal_catch (tag=405267108, 
    func=0x80d0f44 <command_loop_2>, arg=405209180) at eval.c:1030
#20 0x080d0f17 in command_loop () at keyboard.c:1224
#21 0x080d0a91 in recursive_edit_1 () at keyboard.c:950
#22 0x080d0bc0 in Frecursive_edit () at keyboard.c:1006
#23 0x080cfaef in main (argc=2, argv=0xbffffc74, envp=0xbffffc80)
    at emacs.c:1547
(gdb) l
1771      if (WINDOWP (obj))
1772        window = obj;
1773      else if (f)
1774        window = FRAME_SELECTED_WINDOW (f);
1775      else
1776        window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1777
1778      windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
1779      GCPRO1 (windows);
1780      best_window = Qnil;
(gdb) p obj
$6 = 1210793848
(gdb) pr
#<buffer *Messages*>
(gdb) p f
$7 = (struct frame *) 0x0
(gdb) p frames
$8 = 405209228
(gdb) pr
t

So I think this is correct: f is 0x0, therefore we are coming to line
1776, call the SELECTED_FRAME macro, which aborts.


The proposed solution at this point is to call kill_emacs in the
SELECTED_FRAME macro instead of abort, because this situation is not
caught in the test in command_loop_1.


Alex.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]