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

262040byte以上の文字列をクリップボードにコピーすると正常に貼り付けできずSEGV #1053

Closed
norio13 opened this Issue May 18, 2017 · 30 comments

Comments

Projects
None yet
7 participants
@norio13

norio13 commented May 18, 2017

質問・報告の内容

(1)
端末を2つ立ち上げます。以下、端末Aと端末Bと呼びます。

(2)
端末Aで262040byte以上のファイルを開いてバッファの内容を"+pでコピーします。
端末Aで262040byte以上のファイルを開いてバッファの内容を全てコピーします。

ヘルプファイルのeval.txtがこのサイズを越えてるのでこのファイルを開きます。

vim -Nu NONE -c 'h eval.txt' -c 'normal! vG$"+y'

eval.txtではなく262040byteのファイルを作成してご検証してくださる場合は上記のコマンドではなく下記のコマンドを実行してください。

fallocate -l 262040 sample.txt
vim -Nu NONE sample.txt -c 'normal! vG$"+y'

(3)
端末BでVimを起動します。

vim -Nu NONE

"+pまたは:regを手入力で実行します。
引数にコマンドを指定してVimを起動すると再現できません。

"+pを押しても先程コピーした文字列とは異なる文字列が貼り付けられました。
262040byte未満の文字列をコピーした場合であれば問題なく貼り付けできました。

(4)
5秒経過してから端末AのVimで適当にキーを押すとSEGVしました。
SEGV後もVimのプロセスが残り続け、killするまで端末Aが操作不能になります。

Vimのバージョン

8.0.599

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

  • Linux Debian jessie 8.8 64bit

その他

端末

  • xfce4-terminal 0.6.3

機能の一覧

+acl             +file_in_path    +mouse_sgr       +tag_old_static
+arabic          +find_in_path    -mouse_sysmouse  -tag_any_white
+autocmd         +float           +mouse_urxvt     -tcl
-balloon_eval    +folding         +mouse_xterm     +termguicolors
-browse          -footer          +multi_byte      +terminfo
++builtin_terms  +fork()          +multi_lang      +termresponse
+byte_offset     +gettext         -mzscheme        +textobjects
+channel         -hangul_input    -netbeans_intg   +timers
+cindent         +iconv           +num64           +title
+clientserver    +insert_expand   +packages        -toolbar
+clipboard       +job             +path_extra      +user_commands
+cmdline_compl   +jumplist        -perl            +vertsplit
+cmdline_hist    +keymap          +persistent_undo +virtualedit
+cmdline_info    +lambda          +postscript      +visual
+comments        +langmap         +printer         +visualextra
+conceal         +libcall         +profile         +viminfo
+cryptv          +linebreak       +python/dyn      +vreplace
+cscope          +lispindent      +python3/dyn     +wildignore
+cursorbind      +listcmds        +quickfix        +wildmenu
+cursorshape     +localmap        +reltime         +windows
+dialog_con      -lua             +rightleft       +writebackup
+diff            +menu            -ruby            +X11
+digraphs        +mksession       +scrollbind      +xfontset
-dnd             +modify_fname    +signs           -xim
-ebcdic          +mouse           +smartindent     -xpm
+emacs_tags      -mouseshape      +startuptime     +xsmp_interact
+eval            +mouse_dec       +statusline      +xterm_clipboard
+ex_extra        -mouse_gpm       -sun_workshop    -xterm_save
+extra_search    -mouse_jsbterm   +syntax
+farsi           +mouse_netterm   +tag_binary
@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 19, 2017

Member

fedora 25 & gnome端末 3.22.1 & Vim 8.0.600 (Huge, with GTK-GNOME)(要は +Clipboard) で試してみましたが再現しませんでした。

確認:
fallocateで作成したsample.txtは以降の手順で使用されていないですけど問題ないでしょうか?

Member

h-east commented May 19, 2017

fedora 25 & gnome端末 3.22.1 & Vim 8.0.600 (Huge, with GTK-GNOME)(要は +Clipboard) で試してみましたが再現しませんでした。

確認:
fallocateで作成したsample.txtは以降の手順で使用されていないですけど問題ないでしょうか?

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 19, 2017

Member

端末をxfce4-terminal 0.8.4に替えてみましたが再現しませんでした。

@norio13 xfce4-terminal以外の端末の場合に再現するか確認をお願いできますか。

Member

h-east commented May 19, 2017

端末をxfce4-terminal 0.8.4に替えてみましたが再現しませんでした。

@norio13 xfce4-terminal以外の端末の場合に再現するか確認をお願いできますか。

@lesguillemets

This comment has been minimized.

Show comment
Hide comment
@lesguillemets

lesguillemets May 19, 2017

Xubuntu 16.10 64 bit 上の xfce4-terminal 0.6.3 (Xfce 4.12) で,以下の手順でSEGVが再現します.

  1. vim -u NONE -N -c 'h eval.txt'
  2. vG$"+y を手打ち(試した限りでは,これを -c で与えても再現しませんでした…そんなことってある?)
  3. 数秒まつ

また,

  • 手元の環境ではプロセスが残り続けるということはなく,ターミナルは SEGV 後も操作可能です.
  • 再現の有無にかかわらず貼り付けは正常にできています.
  • :%y+ では再現しないようです.
  • gvim -u NONE -U NONE -N では再現しません.

vim は 8.0.0599 (HUGE, with GTK2) です.

lesguillemets commented May 19, 2017

Xubuntu 16.10 64 bit 上の xfce4-terminal 0.6.3 (Xfce 4.12) で,以下の手順でSEGVが再現します.

  1. vim -u NONE -N -c 'h eval.txt'
  2. vG$"+y を手打ち(試した限りでは,これを -c で与えても再現しませんでした…そんなことってある?)
  3. 数秒まつ

また,

  • 手元の環境ではプロセスが残り続けるということはなく,ターミナルは SEGV 後も操作可能です.
  • 再現の有無にかかわらず貼り付けは正常にできています.
  • :%y+ では再現しないようです.
  • gvim -u NONE -U NONE -N では再現しません.

vim は 8.0.0599 (HUGE, with GTK2) です.

@lesguillemets

This comment has been minimized.

Show comment
Hide comment
@lesguillemets

lesguillemets May 19, 2017

追記

  • 同環境の gnome-terminal 3.20.2, xterm (Xterm (324)) でも再現しました.
  • + レジスタの関与は必要ではないようで,上の 2. で単に vG$y でも再現しますが,この場合数秒待ったあとに任意のキーを押すとそのタイミングで SEGV します.(??)
  • VGy 系では再現しませんでした.

追記

  • 同環境の gnome-terminal 3.20.2, xterm (Xterm (324)) でも再現しました.
  • + レジスタの関与は必要ではないようで,上の 2. で単に vG$y でも再現しますが,この場合数秒待ったあとに任意のキーを押すとそのタイミングで SEGV します.(??)
  • VGy 系では再現しませんでした.
@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 May 19, 2017

.@h-east ご指摘ありがとうございます。
eval.txtを使う場合はsample.txtは必須ではないです。
(2)を修正致しました。

Vim 8.0.600 (Huge 版 without GUI)にバージョンアップしてから下記の端末で試してみました。

  • xterm 312-2
  • gnome-terminal 3.14.1-1+deb8u1
  • rxvt-unicode 9.20-1+b1
  • guake 0.4.4-1
  • sakura 3.1.5-1

rxvt-unicodeではSEGVではなくABRTが出ましたが、プロセスが残らないので操作不能にはなりませんでした。
それ以外の端末ではxfce4-terminalと同様にSEGVが出てプロセスが残り操作不能になります。

@lesguillemets ご検証に感謝致します。

norio13 commented May 19, 2017

.@h-east ご指摘ありがとうございます。
eval.txtを使う場合はsample.txtは必須ではないです。
(2)を修正致しました。

Vim 8.0.600 (Huge 版 without GUI)にバージョンアップしてから下記の端末で試してみました。

  • xterm 312-2
  • gnome-terminal 3.14.1-1+deb8u1
  • rxvt-unicode 9.20-1+b1
  • guake 0.4.4-1
  • sakura 3.1.5-1

rxvt-unicodeではSEGVではなくABRTが出ましたが、プロセスが残らないので操作不能にはなりませんでした。
それ以外の端末ではxfce4-terminalと同様にSEGVが出てプロセスが残り操作不能になります。

@lesguillemets ご検証に感謝致します。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 25, 2017

Member

どなたか、-g 付きでビルドしたvimをgdbで動かしてSEGVした時のバックトレースを貼っていただけないでしょうか?
分からないことがあれば聞いて下さい。

とりあえずUbuntuでgdbする場合はこの設定変更が必要です。
http://mylog.cswiki.jp/index.php?APL%2Fgdb

Member

h-east commented May 25, 2017

どなたか、-g 付きでビルドしたvimをgdbで動かしてSEGVした時のバックトレースを貼っていただけないでしょうか?
分からないことがあれば聞いて下さい。

とりあえずUbuntuでgdbする場合はこの設定変更が必要です。
http://mylog.cswiki.jp/index.php?APL%2Fgdb

@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 May 25, 2017

初めてgdbを使うので自信ないので手順も載せます。
間違っている箇所のご指摘お願いいたします。
gdb 7.7.1+dfsg-5です。

(1)端末A vim -Nu NONE -c 'h eval.txt' -c 'normal! vG$"+y'
(2)端末C gdb -p $(pgrep vim)してからgdbの中でcontinueコマンドを実行。
(3)端末B vim -Nu NONEしてから"+pを押す。
(4)端末A 5秒過ぎてからESCキーを押す。
(5)端末Cのgdbに下記メッセージが表示されました。

Program received signal SIGSEGV, Segmentation fault.
mem2chunk_check (mem=mem@entry=0x7fe5bc553010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
169	hooks.c: そのようなファイルやディレクトリはありません.

(6)gdbでbacktraceコマンドを実行すると次のメッセージが表示されました。

#0  mem2chunk_check (mem=mem@entry=0x7fe5bc553010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
#1  0x00007fe5bd964c70 in free_check (mem=0x7fe5bc553010, caller=<optimized out>) at hooks.c:293
#2  0x00007fe5be73e9d6 in ?? () from /usr/lib/x86_64-linux-gnu/libXt.so.6
#3  0x00007fe5be7366a0 in XtAppProcessEvent ()
   from /usr/lib/x86_64-linux-gnu/libXt.so.6
#4  0x0000000000516728 in ?? ()
#5  0x0000000000514750 in ?? ()
#6  0x000000000051430c in ?? ()
#7  0x00000000005a3e25 in ?? ()
#8  0x00000000005a3df6 in ?? ()
#9  0x000000000049eab4 in ?? ()
#10 0x000000000049e367 in ?? ()
#11 0x000000000049e7fe in ?? ()
#12 0x00000000004e2375 in ?? ()
#13 0x00000000005d6b61 in ?? ()
#14 0x00000000005d643c in ?? ()
#15 0x00000000005d5c82 in ?? ()
---Type <return> to continue, or q <return> to quit---
#16 0x00007fe5bd90cb45 in __libc_start_main (main=0x5d58f6, argc=7, 
    argv=0x7ffd407b8538, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7ffd407b8528) at libc-start.c:287
#17 0x00000000004051f9 in ?? ()

norio13 commented May 25, 2017

初めてgdbを使うので自信ないので手順も載せます。
間違っている箇所のご指摘お願いいたします。
gdb 7.7.1+dfsg-5です。

(1)端末A vim -Nu NONE -c 'h eval.txt' -c 'normal! vG$"+y'
(2)端末C gdb -p $(pgrep vim)してからgdbの中でcontinueコマンドを実行。
(3)端末B vim -Nu NONEしてから"+pを押す。
(4)端末A 5秒過ぎてからESCキーを押す。
(5)端末Cのgdbに下記メッセージが表示されました。

Program received signal SIGSEGV, Segmentation fault.
mem2chunk_check (mem=mem@entry=0x7fe5bc553010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
169	hooks.c: そのようなファイルやディレクトリはありません.

(6)gdbでbacktraceコマンドを実行すると次のメッセージが表示されました。

#0  mem2chunk_check (mem=mem@entry=0x7fe5bc553010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
#1  0x00007fe5bd964c70 in free_check (mem=0x7fe5bc553010, caller=<optimized out>) at hooks.c:293
#2  0x00007fe5be73e9d6 in ?? () from /usr/lib/x86_64-linux-gnu/libXt.so.6
#3  0x00007fe5be7366a0 in XtAppProcessEvent ()
   from /usr/lib/x86_64-linux-gnu/libXt.so.6
#4  0x0000000000516728 in ?? ()
#5  0x0000000000514750 in ?? ()
#6  0x000000000051430c in ?? ()
#7  0x00000000005a3e25 in ?? ()
#8  0x00000000005a3df6 in ?? ()
#9  0x000000000049eab4 in ?? ()
#10 0x000000000049e367 in ?? ()
#11 0x000000000049e7fe in ?? ()
#12 0x00000000004e2375 in ?? ()
#13 0x00000000005d6b61 in ?? ()
#14 0x00000000005d643c in ?? ()
#15 0x00000000005d5c82 in ?? ()
---Type <return> to continue, or q <return> to quit---
#16 0x00007fe5bd90cb45 in __libc_start_main (main=0x5d58f6, argc=7, 
    argv=0x7ffd407b8538, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7ffd407b8528) at libc-start.c:287
#17 0x00000000004051f9 in ?? ()
@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 May 25, 2017

調べてたらVimのヘルプのtodo.txtに今回報告させて頂いたのと同根?の内容が記載されているのを見つけました。

X11: Putting more than about 262040 characters of text on the clipboard and
pasting it in another Vim doesn't work.  (Dominique Pelle, 2008 Aug 21-23)
clip_x11_request_selection_cb() is called with zero value and length.
Also: Get an error message from free() in the process that owns the selection.
Seems to happen when the selection is requested the second time, but before
clip_x11_convert_selection_cb() is invoked, thus in X library code.

norio13 commented May 25, 2017

調べてたらVimのヘルプのtodo.txtに今回報告させて頂いたのと同根?の内容が記載されているのを見つけました。

X11: Putting more than about 262040 characters of text on the clipboard and
pasting it in another Vim doesn't work.  (Dominique Pelle, 2008 Aug 21-23)
clip_x11_request_selection_cb() is called with zero value and length.
Also: Get an error message from free() in the process that owns the selection.
Seems to happen when the selection is requested the second time, but before
clip_x11_convert_selection_cb() is invoked, thus in X library code.
@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 25, 2017

Member

@norio13 チャレンジありがとうございます👍
↓これで、も一回お願いします。
端末AとCでは vim じゃなくて ./vimです。念のため。

デバッグ版Vimのビルドと実行

端末A
$ cd あなたの/vim/src
$ make distclean
$ ./configure CFLAGS='-ggdb3' あなたのconfigureオプション達
$ make
$ ./vim -Nu NONE -c 'h eval.txt' -c 'normal! vG$"+y'

gdbでvimプロセスへアタッチ

端末C
$ cd あなたの/vim/src
$ pgrep -fl vim     # redhat系は pgrep -a vim
(端末Aで実行しているvimのプロセス番号が表示されているので覚える)
$ gdb ./vim 端末Aで実行しているvimのプロセス番号
c              # gdbでcを入力してEnter

端末B
$ vim -Nu NONE    # してから"+pを押す

端末A
5秒過ぎてからESCキーを押す。

すると、端末CのgdbがSEGFするので bt でバックトレースを表示させる。

Member

h-east commented May 25, 2017

@norio13 チャレンジありがとうございます👍
↓これで、も一回お願いします。
端末AとCでは vim じゃなくて ./vimです。念のため。

デバッグ版Vimのビルドと実行

端末A
$ cd あなたの/vim/src
$ make distclean
$ ./configure CFLAGS='-ggdb3' あなたのconfigureオプション達
$ make
$ ./vim -Nu NONE -c 'h eval.txt' -c 'normal! vG$"+y'

gdbでvimプロセスへアタッチ

端末C
$ cd あなたの/vim/src
$ pgrep -fl vim     # redhat系は pgrep -a vim
(端末Aで実行しているvimのプロセス番号が表示されているので覚える)
$ gdb ./vim 端末Aで実行しているvimのプロセス番号
c              # gdbでcを入力してEnter

端末B
$ vim -Nu NONE    # してから"+pを押す

端末A
5秒過ぎてからESCキーを押す。

すると、端末CのgdbがSEGFするので bt でバックトレースを表示させる。

@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 May 25, 2017

教えてくださった手順でやってみました。
先程のは#17までありましたが今回のは#15までです。

#0  mem2chunk_check (mem=mem@entry=0x7f0a60c60010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
#1  0x00007f0a62071c70 in free_check (mem=0x7f0a60c60010, 
    caller=<optimized out>) at hooks.c:293
#2  0x00007f0a62e4b9d6 in ?? () from /usr/lib/x86_64-linux-gnu/libXt.so.6
#3  0x00007f0a62e436a0 in XtAppProcessEvent ()
   from /usr/lib/x86_64-linux-gnu/libXt.so.6
#4  0x0000000000516728 in xterm_update () at os_unix.c:7327
#5  0x0000000000514750 in RealWaitForChar (fd=0, msec=0, check_for_gpm=0x0, 
    interrupted=0x0) at os_unix.c:5818
#6  0x000000000051430c in mch_breakcheck (force=0) at os_unix.c:5465
#7  0x00000000005a3e25 in ui_breakcheck_force (force=0) at ui.c:376
#8  0x00000000005a3df6 in ui_breakcheck () at ui.c:356
#9  0x000000000049eab4 in vgetorpeek (advance=1) at getchar.c:2039
#10 0x000000000049e367 in vgetc () at getchar.c:1603
#11 0x000000000049e7fe in safe_vgetc () at getchar.c:1799
#12 0x00000000004e2375 in normal_cmd (oap=0x7ffcd12e3500, toplevel=1)
    at normal.c:628
#13 0x00000000005d6b61 in main_loop (cmdwin=0, noexmode=0) at main.c:1332
---Type <return> to continue, or q <return> to quit---
#14 0x00000000005d643c in vim_main2 () at main.c:885
#15 0x00000000005d5c82 in main (argc=7, argv=0x7ffcd12e36f8) at main.c:419

norio13 commented May 25, 2017

教えてくださった手順でやってみました。
先程のは#17までありましたが今回のは#15までです。

#0  mem2chunk_check (mem=mem@entry=0x7f0a60c60010, magic_p=magic_p@entry=0x0)
    at hooks.c:169
#1  0x00007f0a62071c70 in free_check (mem=0x7f0a60c60010, 
    caller=<optimized out>) at hooks.c:293
#2  0x00007f0a62e4b9d6 in ?? () from /usr/lib/x86_64-linux-gnu/libXt.so.6
#3  0x00007f0a62e436a0 in XtAppProcessEvent ()
   from /usr/lib/x86_64-linux-gnu/libXt.so.6
#4  0x0000000000516728 in xterm_update () at os_unix.c:7327
#5  0x0000000000514750 in RealWaitForChar (fd=0, msec=0, check_for_gpm=0x0, 
    interrupted=0x0) at os_unix.c:5818
#6  0x000000000051430c in mch_breakcheck (force=0) at os_unix.c:5465
#7  0x00000000005a3e25 in ui_breakcheck_force (force=0) at ui.c:376
#8  0x00000000005a3df6 in ui_breakcheck () at ui.c:356
#9  0x000000000049eab4 in vgetorpeek (advance=1) at getchar.c:2039
#10 0x000000000049e367 in vgetc () at getchar.c:1603
#11 0x000000000049e7fe in safe_vgetc () at getchar.c:1799
#12 0x00000000004e2375 in normal_cmd (oap=0x7ffcd12e3500, toplevel=1)
    at normal.c:628
#13 0x00000000005d6b61 in main_loop (cmdwin=0, noexmode=0) at main.c:1332
---Type <return> to continue, or q <return> to quit---
#14 0x00000000005d643c in vim_main2 () at main.c:885
#15 0x00000000005d5c82 in main (argc=7, argv=0x7ffcd12e36f8) at main.c:419
@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 26, 2017

Member

@norio13 Thanks!👍
#4#15がVimで、#0#3がX11 toolkitですね。
うーん、Vimからはなんともならないのかなぁ。。
(週末に時間取れれば) X11 toolkitのソース見てみます。

Member

h-east commented May 26, 2017

@norio13 Thanks!👍
#4#15がVimで、#0#3がX11 toolkitですね。
うーん、Vimからはなんともならないのかなぁ。。
(週末に時間取れれば) X11 toolkitのソース見てみます。

@lesguillemets

This comment has been minimized.

Show comment
Hide comment
@lesguillemets

lesguillemets May 26, 2017

こちらでも同じバックトレースが得られました.(一応ご報告)

こちらでも同じバックトレースが得られました.(一応ご報告)

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 26, 2017

Member

@lesguillemets ありがとうございます👍

Member

h-east commented May 26, 2017

@lesguillemets ありがとうございます👍

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn May 26, 2017

Member

ウェブで検索しても同様のエラーが見付からないので vim が原因かもと思っています。
clip_x11_convert_selection_cb の中でどこかメモリを壊している、など。

Member

mattn commented May 26, 2017

ウェブで検索しても同様のエラーが見付からないので vim が原因かもと思っています。
clip_x11_convert_selection_cb の中でどこかメモリを壊している、など。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 29, 2017

Member

よし!再現できました!!しかも単一の端末だけだし、クリップボードも使わない。

$ ./vim -Nu NONE -c "h eval.txt"

した後、vG$yして Ggg のセットを繰り返すだけ。私の環境だと2回か3回でSEGVします。
vG$yは手打ちじゃないと発生しないようです。

環境:
fedora 25, gnome端末(3.22.1), Vim 8.0.600
(Windows 10からUltra VNC経由でアクセスしています)

Member

h-east commented May 29, 2017

よし!再現できました!!しかも単一の端末だけだし、クリップボードも使わない。

$ ./vim -Nu NONE -c "h eval.txt"

した後、vG$yして Ggg のセットを繰り返すだけ。私の環境だと2回か3回でSEGVします。
vG$yは手打ちじゃないと発生しないようです。

環境:
fedora 25, gnome端末(3.22.1), Vim 8.0.600
(Windows 10からUltra VNC経由でアクセスしています)

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 29, 2017

Member
$ ./vim -Nu NONE -c "h eval.txt"

して、vGして2秒間隔くらいでEsc押しても2~3回でSEGVする。

gdbで以下のクリップボード関連calbackにbreak貼って酒の肴にする感じですね。
clip_x11_convert_selection_cb()が犯人説濃厚。

b clip_x11_convert_selection_cb
b clip_x11_request_selection_cb
b clip_x11_lose_ownership_cb
b clip_x11_timestamp_cb
Member

h-east commented May 29, 2017

$ ./vim -Nu NONE -c "h eval.txt"

して、vGして2秒間隔くらいでEsc押しても2~3回でSEGVする。

gdbで以下のクリップボード関連calbackにbreak貼って酒の肴にする感じですね。
clip_x11_convert_selection_cb()が犯人説濃厚。

b clip_x11_convert_selection_cb
b clip_x11_request_selection_cb
b clip_x11_lose_ownership_cb
b clip_x11_timestamp_cb
@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east May 30, 2017

Member

あれ?昨日の再現手順を仕事場のfedora (GNOME直アクセス)でやってみてるけど再現しない。
自宅の再現環境を再起動せずに維持しとくしかないですね。

Member

h-east commented May 30, 2017

あれ?昨日の再現手順を仕事場のfedora (GNOME直アクセス)でやってみてるけど再現しない。
自宅の再現環境を再起動せずに維持しとくしかないですね。

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn May 30, 2017

Member

X のバグ説

Member

mattn commented May 30, 2017

X のバグ説

@todashuta

This comment has been minimized.

Show comment
Hide comment
@todashuta

todashuta May 30, 2017

Member
  • Ubuntu 16.04.2 LTS
  • GNOME端末 3.18.3
  • Vim 8.0.606

で再現しました。

Member

todashuta commented May 30, 2017

  • Ubuntu 16.04.2 LTS
  • GNOME端末 3.18.3
  • Vim 8.0.606

で再現しました。

@todashuta

This comment has been minimized.

Show comment
Hide comment
@todashuta

todashuta May 30, 2017

Member

vG$してから、yを押す前に5秒くらい間隔をあけるとyの押下後すぐにSEGVしました。

Member

todashuta commented May 30, 2017

vG$してから、yを押す前に5秒くらい間隔をあけるとyの押下後すぐにSEGVしました。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jun 4, 2017

Member

libXt-1.1.5 のソース落としてきて ./configure CFLAGS='-ggdb3'; make; make install 出来たけどこっちのライブラリ見てくれない。。
...みたいな感じでまったりやっております。寒い季節になるまでには直す!!

Member

h-east commented Jun 4, 2017

libXt-1.1.5 のソース落としてきて ./configure CFLAGS='-ggdb3'; make; make install 出来たけどこっちのライブラリ見てくれない。。
...みたいな感じでまったりやっております。寒い季節になるまでには直す!!

@mattn

This comment has been minimized.

Show comment
Hide comment
@mattn

mattn Jun 4, 2017

Member

LD_PRELOAD してみてはどうでしょう

Member

mattn commented Jun 4, 2017

LD_PRELOAD してみてはどうでしょう

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jul 6, 2017

Member

本件と同根と思われるバグ報告が vim_dev にありました。

[vim/vim] segfault handling large file in visual mode (#1822)
https://groups.google.com/d/msg/vim_dev/opYdlWh84uQ/GJUwUuqZBQAJ

Member

h-east commented Jul 6, 2017

本件と同根と思われるバグ報告が vim_dev にありました。

[vim/vim] segfault handling large file in visual mode (#1822)
https://groups.google.com/d/msg/vim_dev/opYdlWh84uQ/GJUwUuqZBQAJ

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 7, 2017

Member

https://gist.github.com/ichizok/548dda4bd3839a517c5b0a66d4cbf3e5
単体で落ちるケースは手元で再現しないので確認できてませんが、最初の報告のケースはこれで動きました。

Member

ichizok commented Jul 7, 2017

https://gist.github.com/ichizok/548dda4bd3839a517c5b0a66d4cbf3e5
単体で落ちるケースは手元で再現しないので確認できてませんが、最初の報告のケースはこれで動きました。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jul 7, 2017

Member

@ichizok patchをあてて単体で落ちるケースを確認しました。バッチリ👍です。何回やっても落ちません。

Member

h-east commented Jul 7, 2017

@ichizok patchをあてて単体で落ちるケースを確認しました。バッチリ👍です。何回やっても落ちません。

@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 Jul 7, 2017

ありがとうございます。
ichizokさんのpatchでSEGVしなくなりました。
文字列も正常に貼り付けできました。

norio13 commented Jul 7, 2017

ありがとうございます。
ichizokさんのpatchでSEGVしなくなりました。
文字列も正常に貼り付けできました。

@ichizok

This comment has been minimized.

Show comment
Hide comment
@ichizok

ichizok Jul 7, 2017

Member

@h-east @norio13 検証ありがとうございます。

原因を掴みきれてないので、以下推測。

問題を「貼り付け内容が正しくない」と「SEGVする」に分けます。

貼り付け内容が正しくない

これは以下の変更だけでも直るようです。

  • PropertyNotify イベントを優先して処理する
--- a/src/ui.c
+++ b/src/ui.c
@@ -2276,9 +2276,9 @@ clip_x11_request_selection(
        start_time = time(NULL);
        while (success == MAYBE)
        {
-           if (XCheckTypedEvent(dpy, SelectionNotify, &event)
-                   || XCheckTypedEvent(dpy, SelectionRequest, &event)
-                   || XCheckTypedEvent(dpy, PropertyNotify, &event))
+           if (XCheckTypedEvent(dpy, PropertyNotify, &event)
+                   || XCheckTypedEvent(dpy, SelectionNotify, &event)
+                   || XCheckTypedEvent(dpy, SelectionRequest, &event))
            {
                /* This is where clip_x11_request_selection_cb() should be
                 * called.  It may actually happen a bit later, so we loop

libxt のソースから、

  • 262040byte 以上のセレクションが要求される際には分割して処理される
  • 所有側では 262040byte ずつ送信するために SendIncrement() が呼ばれ、その中の XChangeProperty() で要求側にイベントが投げられる
  • 所有側が全てのデータを送信したら AllSent() が呼ばれ、要求側に value=0x0, length=0 のイベントが投げられる

そのため、要求側は PropertyNotify を優先して処理する必要があるのではないか。

SEGV する

何度か試したところでは、貼り付け内容がおかしいときにセレクション所有側が SEGV していた。

  • libxt の OwnerTimedOut() でセレクションデータを解放しようとして不正領域を free している
  • 前述の貼り付け内容の修正を入れると落ちなくなった

よって、要求側がイベントを取りこぼしている(か、イベントの処理順がおかしい)のが原因ではないか。
実際、所有側でメモリリークしている様子があった。

修正を入れたVim同士だと問題ないが、修正されてないVimとか他のプログラムからセレクション要求されるとやっぱり所有側のVimが(修正済みでも)落ちる。

libxmu を参考に、セレクション所有側の処理にも修正を入れた。

  • XtOwnSelection() の notify コールバックを設定
    → セレクションデータは libxt 側で解放されなくなる。
  • clip_x11_convert_selection_cb() 内で確保するメモリハンドルを静的に保持する
    → セレクションデータのメモリ管理をVim側で行う。
Member

ichizok commented Jul 7, 2017

@h-east @norio13 検証ありがとうございます。

原因を掴みきれてないので、以下推測。

問題を「貼り付け内容が正しくない」と「SEGVする」に分けます。

貼り付け内容が正しくない

これは以下の変更だけでも直るようです。

  • PropertyNotify イベントを優先して処理する
--- a/src/ui.c
+++ b/src/ui.c
@@ -2276,9 +2276,9 @@ clip_x11_request_selection(
        start_time = time(NULL);
        while (success == MAYBE)
        {
-           if (XCheckTypedEvent(dpy, SelectionNotify, &event)
-                   || XCheckTypedEvent(dpy, SelectionRequest, &event)
-                   || XCheckTypedEvent(dpy, PropertyNotify, &event))
+           if (XCheckTypedEvent(dpy, PropertyNotify, &event)
+                   || XCheckTypedEvent(dpy, SelectionNotify, &event)
+                   || XCheckTypedEvent(dpy, SelectionRequest, &event))
            {
                /* This is where clip_x11_request_selection_cb() should be
                 * called.  It may actually happen a bit later, so we loop

libxt のソースから、

  • 262040byte 以上のセレクションが要求される際には分割して処理される
  • 所有側では 262040byte ずつ送信するために SendIncrement() が呼ばれ、その中の XChangeProperty() で要求側にイベントが投げられる
  • 所有側が全てのデータを送信したら AllSent() が呼ばれ、要求側に value=0x0, length=0 のイベントが投げられる

そのため、要求側は PropertyNotify を優先して処理する必要があるのではないか。

SEGV する

何度か試したところでは、貼り付け内容がおかしいときにセレクション所有側が SEGV していた。

  • libxt の OwnerTimedOut() でセレクションデータを解放しようとして不正領域を free している
  • 前述の貼り付け内容の修正を入れると落ちなくなった

よって、要求側がイベントを取りこぼしている(か、イベントの処理順がおかしい)のが原因ではないか。
実際、所有側でメモリリークしている様子があった。

修正を入れたVim同士だと問題ないが、修正されてないVimとか他のプログラムからセレクション要求されるとやっぱり所有側のVimが(修正済みでも)落ちる。

libxmu を参考に、セレクション所有側の処理にも修正を入れた。

  • XtOwnSelection() の notify コールバックを設定
    → セレクションデータは libxt 側で解放されなくなる。
  • clip_x11_convert_selection_cb() 内で確保するメモリハンドルを静的に保持する
    → セレクションデータのメモリ管理をVim側で行う。
@k-takata

This comment has been minimized.

Show comment
Hide comment
@k-takata

k-takata Jul 19, 2017

Member

8.0.0737 で取り込まれました。
https://groups.google.com/d/topic/vim_dev/nEaBYPFNkxM/discussion
が、何かコメントが付いていますね。

Member

k-takata commented Jul 19, 2017

8.0.0737 で取り込まれました。
https://groups.google.com/d/topic/vim_dev/nEaBYPFNkxM/discussion
が、何かコメントが付いていますね。

@h-east

This comment has been minimized.

Show comment
Hide comment
@h-east

h-east Jul 22, 2017

Member

が、何かコメントが付いていますね。

気にしなくて良いと思います。
Bram氏も言っているように、8.0.0737 は少なくともクラッシュするのが改善されているし、ヤンク、ペーストも正しくおこなえるようになっています。
もし、問題が発覚したらまた皆で修正すればいいと考えます。
ですので閉じます。

@ichizok 👍 🥇

Member

h-east commented Jul 22, 2017

が、何かコメントが付いていますね。

気にしなくて良いと思います。
Bram氏も言っているように、8.0.0737 は少なくともクラッシュするのが改善されているし、ヤンク、ペーストも正しくおこなえるようになっています。
もし、問題が発覚したらまた皆で修正すればいいと考えます。
ですので閉じます。

@ichizok 👍 🥇

@norio13

This comment has been minimized.

Show comment
Hide comment
@norio13

norio13 Jul 22, 2017

@ichizok Vimの範囲を越えての調査から修正まで改めて感謝を申し上げます。
ありがとうございます。

issueにお付き合いくださった方々もありがとうございます。

norio13 commented Jul 22, 2017

@ichizok Vimの範囲を越えての調査から修正まで改めて感謝を申し上げます。
ありがとうございます。

issueにお付き合いくださった方々もありがとうございます。

@h-east h-east referenced this issue Jul 27, 2017

Closed

端末機能について議論する #1057

20 of 21 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment