Subject: Re: bug#22873: Can we support multiple Cursors?

From: Eli Zaretskii <[email-masked]>
Date: Mon, 14 Mar 2016 20:49:17 +0200

> Date:  Mon, 14 Mar 2016 11:35:18 -0700
> From:  Keith David Bershatsky <[email-masked]>
> Cc:  [email-masked],John Wiegley <[email-masked]>,Marcin Borkowski <[email-masked]>,Richard Stallman <[email-masked]>
> 
> I reached a roadblock on Emacs for Windows and I haven't the slightest idea why my cached list of multiple cursors is being converted into a value `<optimized out>` sporadically when holding down the arrow key and moving the active cursor repetitively through plain text in a fundamental-mode buffer.  Emacs crashes in that circumstance.  The cache is a Lisp_Object pointer defined in `window.h` named mc_cache (aka `w->mc_cache`).  The value of `w->mc_cache` is:
> 
>   '((
>     (3 hbar [1.0 0.0 0.0])
>     (4 bar [0.0 1.0 0.0])
>     (5 box [0.0 0.0 1.0])
>     (6 hollow [0.8 0.4 0.2])
>     (7 (hbar 3) [1.0 0.0 1.0])
>     (8 (bar 3) [0.0 1.0 1.0]))
>    (
>     ((3 hbar [1.0 0.0 0.0]) (22 20 2 0))
>     ((4 bar [0.0 1.0 0.0]) (33 20 3 0))
>     ((5 box [0.0 0.0 1.0]) (44 20 4 0))
>     ((6 hollow [0.8 0.4 0.2]) (55 20 5 0))
>     ((7 (hbar 3) [1.0 0.0 1.0]) (66 20 6 0))
>     ((8 (bar 3) [0.0 1.0 1.0]) (77 20 7 0))
>     ))
> 
> The "for" loop looks like this and Emacs crashes when reading the line containing "cursor_spec_list = XCAR (XCAR (vlist))".  `cursor_spec_list` and `vlist` are both Lisp_Object:
> 
>    for (vlist = XCAR (XCDR (w->mc_cache));
>         CONSP (vlist);
>         vlist = XCDR (vlist))
>      {
>        cursor_spec_list = XCAR (XCAR (vlist));
>        ***

You maintain a Lisp object in a window object, but did you make sure
it's declared before the place in 'struct window' where we have this
comment:

    /* No Lisp data may follow below this point without changing
       mark_object in alloc.c.  The member current_matrix must be the
       first non-Lisp member.  */

If mc_cache is beyond this point, chances are it's being GC'ed behind
your back.