Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自動コマンドからタブ操作とバッファ削除するとSEGVする #933

Closed
norio13 opened this issue Jul 15, 2016 · 18 comments
Closed

Comments

@norio13
Copy link

norio13 commented Jul 15, 2016

質問・報告の内容

SEGVするコードを見つけたので報告します。

サンプル1

vim -Nu NONE -S sample1.vim

edit a.txt

augroup sample
    autocmd!
    autocmd BufUnload <buffer> tabfirst | 2bwipeout!
augroup END

edit b.txt

:bw!で再現します。:bun!と:bd!では再現しません。

再現するイベント

  • BufUnload
  • BufWinLeave

再現しないイベント

  • BufDelete
  • BufHidden
  • BufLeave
  • BufWipeout

サンプル2

vim -Nu NONE -S sample2.vim

setlocal buftype=nowrite

augroup sample
    autocmd!
    autocmd BufUnload <buffer> tabfirst | 2bwipeout
augroup END

normal! i1
edit a.txt

call feedkeys("\<CR>")

:bw!で再現します。:bun!と:bd!では再現しません。
:bwで再現します。:bunと:bdでは再現しません。

再現するイベント

  • BufUnload
  • BufDelete
  • BufWinLeave

再現しないイベント

  • BufHidden
  • BufLeave
  • BufWipeout

サンプル3

vim -Nu NONE -S sample3.vim

tabedit

augroup sample
    autocmd!
    autocmd BufUnload <buffer> tabfirst
augroup END

:%!ls
edit! a.txt
normal! gt
:%!ls

call feedkeys("\<CR>q::q\<CR>")

再現するイベント

  • BufUnload
  • BufDelete
  • BufWinLeave

再現しないイベント

  • BufHidden
  • BufLeave
  • BufWipeout

Vimのバージョン

7.4.2038

OSの種類/ディストリ/バージョン

Linux Debian 8.5 (jessie) 64bit

@mattn
Copy link
Member

mattn commented Jul 15, 2016

サンプル1、サンプル2は解決。サンプル3は以下のパッチをあてても(落ちはしないけど)本来見えちゃダメな E315 が出るけど、curwin->w_buffer が NULL というバッファ移動の途中経過を見せないためにも一度カレントバッファを設定した方が安全かと思いますね。

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 7ec17b1..302d055 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4389,6 +4389,11 @@ delbuf_msg(char_u *name)
        name == NULL ? (char_u *)"" : name);
     vim_free(name);
     au_new_curbuf.br_buf = NULL;
+
+# ifdef FEAT_WINDOWS
+    if (curwin->w_buffer == NULL)
+   enter_buffer(curbuf);
+# endif
 }
 #endif

このコードは buffer.c でもやられている手なのでそれほど悪い手ではないと思う。

@norio13
Copy link
Author

norio13 commented Jul 16, 2016

patch作成してくださりありがとうございます。
私の環境ではpatch適用後もサンプル3でSEGVしました。
一瞬チラついてから落ちるのでE315や他のエラーが出たかどうか確認できておりません。

サンプル1とサンプル2についてはSEGVが出なくなりました。
ただ、タブを閉じるときにエラーが出たので、確認するためにタブを新規に作成して自動コマンドを設定したタブに戻って閉じる処理を加えるとSEGVが出ました。
再現するのはBufWinLeaveイベントを指定した時のみです。

sample1a.vim:

edit a.txt

augroup sample
    autocmd!
    autocmd BufWinLeave <buffer> tabfirst | 2bw!
augroup END

edit b.txt
tabedit
tabfirst
quit

sample2a.vim:

setlocal buftype=nowrite

augroup sample
    autocmd!
    autocmd BufWinLeave <buffer> tabfirst | 2bw
augroup END

normal! i1
edit a.txt

call feedkeys("\<CR>")
tabedit
tabfirst
quit

@h-east
Copy link
Member

h-east commented Jul 23, 2016

まっつんさんのpatchに変更を加えました。
sample1a.vim, sample2a.vimでも落ちなくなりました。
https://gist.github.com/h-east/9f2322ec5225f54d61071d040e1351a5

残るはsample3.vim

@mattn
Copy link
Member

mattn commented Jul 24, 2016

そう、sample3 がなかなか手ごわい。

@h-east
Copy link
Member

h-east commented Jul 29, 2016

patch更新。このissueで報告されている問題すべて解決したと思います。
https://gist.github.com/h-east/9f2322ec5225f54d61071d040e1351a5

sample3.vimはbuf解放時のautocommand処理でカレントタブページが移動していたらエラーにするようにしました。
たぶん、他の部分も見なおして修正が必要な箇所を直さないといけないと思いますが、まずはお試しを。

@h-east
Copy link
Member

h-east commented Jul 30, 2016

あぅ、make testで10ほどエラーになってる。

@h-east
Copy link
Member

h-east commented Jul 30, 2016

Fixed:+1:

@norio13
Copy link
Author

norio13 commented Jul 30, 2016

ご対応ありがとうございます。
Vim 7.4.2121にpatchを適用して確認してみた所、サンプル3でBufWinLeaveイベントを指定した場合のみSEGVで落ちました。

@h-east
Copy link
Member

h-east commented Jul 30, 2016

@norio13 確認ありがとうございます。patch更新しました。(Rev. 4)

@norio13
Copy link
Author

norio13 commented Jul 30, 2016

@h-east patch(Rev.4)適用でSEGVしなくなりました。
ありがとうございます。

@h-east
Copy link
Member

h-east commented Aug 6, 2016

このpatchですが、autocommandでカレントタブページが移動したらその時点でメッセージも出さずに処理を終わらせているのでよろしくない気がしています。
っと言っても現状でも対象バッファが変更になったらメッセージ無しで処理やめちゃうのでこのままでいいかな?
SEGVするよりはマシってことで。

@h-east h-east self-assigned this Aug 24, 2016
@h-east
Copy link
Member

h-east commented Sep 4, 2016

patch 7.4.2312 by Bram
vim/vim@5a49789
このpatchでsample3.vimがSEGVしなくなったのは確認しました。

残念ながらsample1.vimとsample2.vimは現時点の最新(7.4.2312)でもSEGVします。
まずはtest_autocmd.vimにテスト追加したんだけど落ちない。。単独(vim -Nu NONE -S sample?.vim)でやると落ちる。。
もうちょい調べます。

@h-east
Copy link
Member

h-east commented Sep 4, 2016

patch前のtestでSEGVしないけど、諦めてvim_devに投げました。
https://groups.google.com/d/msg/vim_dev/Gao-PqyS6Tk/IRn1pC_uCQAJ

@norio13
Copy link
Author

norio13 commented Sep 4, 2016

調査と報告ありがとうございます。

vim 7.4.2322
sample3.vimでBufWinLeaveを指定すると落ちました。

@h-east
Copy link
Member

h-east commented Sep 4, 2016

@norio13 7.4.2323 + 私が投げたpatchだと落ちないです。
「このケースのSEGVも直るよ」と追加報告しておきます。

@norio13
Copy link
Author

norio13 commented Sep 4, 2016

@h-east sample1.vimとsample2.vimの分のみ報告されたのだと勝手に勘違いしてました。
patch適用して全部修正されているのを確認できました。
大変失礼致しました。

@h-east
Copy link
Member

h-east commented Sep 5, 2016

patch 7.4.2324
vim/vim@e0ab94e

patch 7.4.2328
vim/vim@f9e687e

@norio13 説明不足でした。以前作成したpatch(sample1~3全対応)がpatch 7.4.2312(sample3が直ったと思われるもの)とconflictを起こしたので手動でマージして新しくpatchを作成しました。なのでごちゃ混ぜです。

@h-east
Copy link
Member

h-east commented Sep 5, 2016

7.4.2330で全てのscript(sample1~3, sample1a, sample2a)がSEGVしないことを確認しました。
閉じます。ありがとうございました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants