XXX: ex_tabonly(): aucmd_win is not part of the window list.

During free_all_mem, somehow ex_tabonly() may free aucmd_win. But it
isn't fully destroyed (maybe autocmd_busy?). When win_free_all() tries
to free aucmd_win directly, it double-frees the sub-fields.

Tried unnsuccessfully to work around this by invoking `:tabonly!` with
autocmds disabled:

    diff --git a/src/nvim/memory.c b/src/nvim/memory.c
    index 58c01fbe7a12..91c845e94d22 100644
    --- a/src/nvim/memory.c
    +++ b/src/nvim/memory.c
    @@ -565,9 +565,9 @@ void free_all_mem(void)
       /* Close all tabs and windows.  Reset 'equalalways' to avoid redraws. */
       p_ea = false;
       if (first_tabpage->tp_next != NULL)
    -    do_cmdline_cmd("tabonly!");
    +    do_cmdline_cmd("noautocmd tabonly!");
       if (firstwin != lastwin)
    -    do_cmdline_cmd("only!");
    +    do_cmdline_cmd("noautocmd only!");

       /* Free all spell info. */
       spell_free_all();
This commit is contained in:
Justin M. Keyes 2017-03-23 14:07:51 +01:00
parent c398402f12
commit 7214d0bc84

View File

@ -6081,6 +6081,9 @@ static void ex_tabonly(exarg_T *eap)
// Repeat this up to a 1000 times, because autocommands may
// mess up the lists.
for (int done = 0; done < 1000; done++) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
assert(wp != aucmd_win);
}
FOR_ALL_TABS(tp) {
if (tp->tp_topframe != topframe) {
tabpage_close_other(tp, eap->forceit);