Subject: bug#30182: Update

From: Eli Zaretskii <[email-masked]>
Date: Mon, 22 Jan 2018 19:37:54 +0200

> From: Sujith <[email-masked]>
> Cc: Eli Zaretskii <[email-masked]>, [email-masked]
> Date: Mon, 22 Jan 2018 20:39:15 +0530
> 
> martin rudalics <[email-masked]> writes:
> > Can you please do a bt full here: The previous backtrace you posted
> > had result_len = 4 which indicates that `timer-list' contained four
> > timers.  But the above result of pp indicates that there are five
> > timers.  Hence the two backtraces appear incongruent in this regard.
> 
> Here's the trace:

Thanks, but this looks the same as the previous one:

> #4  0x000000000065b2a0 in concat (nargs=1, args=0x7fffffffdbb8, target_type=Lisp_Cons, last_special=false) at fns.c:751
>         elt = XIL(0x34f7435)
>         thislen = make_number(379158388)
>         thisleni = 0
>         thisindex = 0
>         thisindex_byte = 0
>         val = XIL(0x3f45ec3)
>         tail = XIL(0)
>         this = XIL(0)
>         toindex = -1
>         toindex_byte = 0
>         result_len = 4
          ^^^^^^^^^^^^^^
[...]
> (gdb) pp Vtimer_list
> ([nil 23141 64978 246464 0.5 blink-cursor-timer-function nil nil 189000] [nil 23141 64978 302592 nil #[(buffer) "!
> qÃ)" [buffer w3m-modeline-title-timer buffer-live-p nil] 2] (#<buffer *w3m*>) nil 205000] [nil 23141 64978 719575 nil undo-auto--boundary-timer nil nil 383000] [nil 23141 64984 0 60 display-time-event-handler nil nil 0] [nil 23141 65265 921067 300 savehist-autosave nil nil 717000])

The above list has 5 elements, not 4.

Martin, did you try reproducing this on your GNU/Linux box?  Did you
succeed?

Also, could it be that the culprit is this part of the offending
changeset:

     if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
       {
  -      Lisp_Object last_string = AREF (last_show_tip_args, 0);
  -      Lisp_Object last_frame = AREF (last_show_tip_args, 1);
  -      Lisp_Object last_parms = AREF (last_show_tip_args, 2);
  -
	 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
  -         && EQ (frame, last_frame)
  -         && !NILP (Fequal_including_properties (last_string, string))
  -         && !NILP (Fequal (last_parms, parms)))
  +         && EQ (frame, tip_last_frame)
  +         && !NILP (Fequal_including_properties (tip_last_string, string))
  +         && !NILP (Fequal (tip_last_parms, parms)))
	  {
	    /* Only DX and DY have changed.  */
	    tip_f = XFRAME (tip_frame);
	    if (!NILP (tip_timer))
	      {
  -             Lisp_Object timer = tip_timer;
  -
  +             call1 (Qcancel_timer, tip_timer);
		tip_timer = Qnil;
  -             call1 (Qcancel_timer, timer);
	      }

	    block_input ();

Note that the old code copied the tip timer, then nullified it, and
then canceled it using the copy.  While the new code cancels first and
then nullifies.

The crash seems to be caused by an element of timer-list becoming nil
somehow.  We need to understand how that happens.  The relevant
players are (1) the fact that w3m.el schedules a timer from a
mode-line's :eval form, and (2) the tool-tip machinery, in particular
its canceling timer.  And it sounds like by the time copy-sequence
runs and tries to copy timer-list, the damage to the list is already
done.  Also, an important thing to remember is that copy-sequence
copies the list, but doesn't copy the elements, so the elements are
shared with the original list.  Hmm...