Subject: Re: bug#30182: Update

From: martin rudalics <[email-masked]>
Date: Mon, 22 Jan 2018 19:59:28 +0100

> The above list has 5 elements, not 4.

Wouldn't that imply that a timer was added after `copy-sequence'
started?

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

So far I have condensed a ~50 lines excerpt from w3m.el which should
include all necessary ingredients to shorten the mode line text as w3m
does, but to no avail.

 > 	    /* 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.

So that code really had some purpose?  OTOH why would someone had
bothered to write it in the first place.  And if that someone was
Gerd, he probably had enough prior experience with timer variables to
put it there.  Sujith, can you try the attached patch?

 > 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...

The list with the 5 timers seems pretty innocuous to me.  I still
wonder why concat decided to reserve only 4 elements for its copy.

martin
diff --git a/src/xfns.c b/src/xfns.c
index 43c55cc..917fdd5 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6526,8 +6526,10 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
 {
   if (!NILP (tip_timer))
     {
-      call1 (Qcancel_timer, tip_timer);
+      Lisp_Object timer = tip_timer;
+
       tip_timer = Qnil;
+      call1 (Qcancel_timer, timer);
     }
 
 #ifdef USE_GTK
@@ -6759,8 +6761,10 @@ with offset DY added (default is -10).
 	  tip_f = XFRAME (tip_frame);
 	  if (!NILP (tip_timer))
 	    {
-	      call1 (Qcancel_timer, tip_timer);
+	      Lisp_Object timer = tip_timer;
+
 	      tip_timer = Qnil;
+	      call1 (Qcancel_timer, timer);
 	    }
 
 	  block_input ();