(Steps here using docker to ensure maximum reproducibility):
docker run -it --rm alpine:3.15apk add alpine-sdk xxd ncurses-dev lua5.3-dev python3-dev gtk+3.0-dev libx11-dev libxt-devcd ~git clone --depth=1 https://github.com/vim/vim -b v8.2.3584cd vim/./configure --prefix=/usr --enable-luainterp --enable-python3interp=dynamic --without-x --disable-nls --enable-multibyte --enable-gui=no --with-lua-prefix=/usr/lua5.3make -j$(nproc)make installcd /usr/share/vimcurl -o vimrc https://tpaste.us/ovJrvim /etc/ (Or any directory)No segfault.
Alpine Linux v3.15, Docker Image
Started happening after v8.2.3584, still happens on master (v8.2.3770 at time of reporting). Installed package versions: https://tpaste.us/jNgm
Notes: - Segfault happens when there are 3 or more user defined commands anywhere in the vim initialisation procedure (even in plugins) any you open `netrw`. (Commenting out any one of the user defined commands in the example vimrc prevents the segfault from happening). - Segfault doesn't happen if running `vim -u /usr/share/vim/vimrc /etc/`, even though that's the default vimrc. - Segfault doesn't happen if `~/.vimrc` exists (can be completely empty) - According to GDB, the segfault happens in https://github.com/vim/vim/blob/58ef8a31d7087d495ab1582be5b7a22796ac2451/src/usercmd.c#L1778 (line number as of `v8.2.3584`).
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.
![]()
What's the output of :scriptnames when you run just $ vim?
What's the output of :scriptnames when you run $ vim /etc?
@lacygoill When running vim /etc/, it segfaults so I can't get the output of :scriptnames, right? Or am I misunderstanding something?
@lacygoill When running vim /etc/, it segfaults so I can't get the output of :scriptnames, right? Or am I misunderstanding something?
Ah right. My bad. Although, maybe you could start in debug mode:
$ vim -D /etc
And ask for :scriptnames right before the crash. Not sure that's possible.
I'm asking these questions because I can't reproduce:
mv ~/.vim/vimrc{,moved} \
&& mkdir -p /tmp/share/vim \
&& VIM=/tmp/share/vim VIMRUNTIME=/usr/local/share/vim/vim82 vim --cmd 'set rtp-=~/.vim rtp-=~/.vim/after' /etc \
&& mv ~/.vim/vimrc{moved,}
I'm trying to find out the right invocation.
But at least the output of :scriptnames when starting $ vim alone would help me.
@lacygoill Like I noted, if there's a ~/.vimrc file, then the segfault doesn't happen, so I don't know if other things in your invocation are preventing the segfault from happening.
Also, I forgot to mention that the segfault only happens on Alpine.
@lacygoill Like I noted, if there's a ~/.vimrc file, then the segfault doesn't happen, so I don't know if other things in your invocation are preventing the segfault from happening.
That's why my command temporarily moves the vimrc so that Vim can't find it:
mv ~/.vim/vimrc{,moved} \
...
Also, I forgot to mention that the segfault only happens on Alpine.
OK, I'm on Ubuntu 20.04.
Output of :scriptnames: https://tpaste.us/DXRd
@lacygoill With vim -D /etc, this is the line just before the segfault:
cmd: call s:VimEnter(expand("<amatch>")
@lacygoill can you try with the Docker steps I have in the issue?
I'm trying but it's not easy because I don't have docker:
$ docker run -it --rm alpine:3.15
Command 'docker' not found, but can be installed with:
sudo snap install docker # version 19.03.13, or
sudo apt install docker.io # version 20.10.7-0ubuntu5~20.04.2
$ sudo apt install docker
$ docker run -it --rm alpine:3.15
Command 'docker' not found, but can be installed with:
...
I had to install docker.io. But I don't understand the remaining commands, and I don't know what they install, nor where they install files, nor how to remove all of it at the end. But I'm still in the process of running all the commands. I'll need more time.
@lacygoill With vim -D /etc, this is the line just before the segfault:
Thank you very much. FWIW, you can step inside the s:VimEnter() function by executing the :help >step debugging command.
@lacygoill Once you install docker, all the commands after the docker run should be done inside the docker container. Once you're done testing, you can run docker system prune -a which will remove the docker stuff.
apk is the Alpine package keeper, does the same job as apt
@lacygoill Once you install docker, all the commands after the docker run should be done inside the docker container. Once you're done testing, you can run docker system prune -a which will remove the docker stuff.
Thank you, that's helpful.
OK, I can reproduce the crash now. I'm going to try to get some logs.
can you paste the backtrace in gdb, since you already pinpointed the problematic line in gdb?
@chrisbra I'm deep in vim debug mode in the middle of netrw right now, but as soon as I'm done I'll compile vim with debug symbols again and send the backtrace.
thanks. If possible, please also try with an ASAN enabled build :)
@chrisbra Using -fsanitize=address in CFLAGS, CXXFLAGS and LDFLAGS, right?
Here is a backtrace:
#0 0x000055603e50792e in do_ucmd (eap=0x7ffc47734df0) at usercmd.c:1778
#1 0x000055603e34458d in do_one_cmd (cmdlinep=0x7ffc47735020, flags=7, cstack=0x7ffc47735100, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a57a2b0) at ex_docmd.c:2606
#2 0x000055603e3416fa in do_cmdline (cmdline=0x0, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a57a2b0, flags=7) at ex_docmd.c:1000
#3 0x000055603e50e8b8 in call_user_func
(fp=0x7ff67a5016d0, argcount=2, argvars=0x7ffc47735f00, rettv=0x7ffc477360e0, funcexe=
0x7ffc47736110, selfdict=0x0) at userfunc.c:2745
#4 0x000055603e50eef3 in call_user_func_check
(fp=0x7ff67a5016d0, argcount=2, argvars=0x7ffc47735f00, rettv=0x7ffc477360e0, funcexe=
0x7ffc47736110, selfdict=0x0) at userfunc.c:2892
#5 0x000055603e50fd19 in call_func
(funcname=0x7ff67a466a00 "\200\375R22_NetrwBrowse", len=-1, rettv=0x7ffc477360e0, argcount_in=2, argvars_in=0x7ffc47735f00, funcexe=0x7ffc47736110) at userfunc.c:3382
#6 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a466a00 "\200\375R22_NetrwBrowse", len=-1, rettv=0x7ffc477360e0, arg=0x7ffc477360a8, evalarg=0x7ffc47736160, funcexe=0x7ffc47736110) at userfunc.c:1753
#7 0x000055603e513b8e in ex_call (eap=0x7ffc477362a0) at userfunc.c:5029
#8 0x000055603e3445c0 in do_one_cmd (cmdlinep=0x7ffc477364d0, flags=11, cstack=0x7ffc477365b0, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579980) at ex_docmd.c:2614
#9 0x000055603e3416fa in do_cmdline
(cmdline=0x7ff67a48ed30 "keepj keepalt call s:NetrwBrowse(1,a:dirname)", fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579980, flags=11) at ex_docmd.c:1000
#10 0x000055603e50792a in do_ucmd (eap=0x7ffc47736d40) at usercmd.c:1776
#11 0x000055603e34458d in do_one_cmd (cmdlinep=0x7ffc47736f70, flags=7, cstack=0x7ffc47737050, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579980) at ex_docmd.c:2606
#12 0x000055603e3416fa in do_cmdline (cmdline=0x0, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579980, flags=7) at ex_docmd.c:1000
#13 0x000055603e50e8b8 in call_user_func
(fp=0x7ff67a491fa0, argcount=1, argvars=0x7ffc47737e50, rettv=0x7ffc47738030, funcexe=
0x7ffc47738060, selfdict=0x0) at userfunc.c:2745
#14 0x000055603e50eef3 in call_user_func_check
(fp=0x7ff67a491fa0, argcount=1, argvars=0x7ffc47737e50, rettv=0x7ffc47738030, funcexe=
0x7ffc47738060, selfdict=0x0) at userfunc.c:2892
#15 0x000055603e50fd19 in call_func
(funcname=0x7ff67a598bf0 "netrw#LocalBrowseCheck", len=-1, rettv=0x7ffc47738030, argcount_in=1, argvars_in=0x7ffc47737e50, funcexe=0x7ffc47738060) at userfunc.c:3382
#16 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a598bf0 "netrw#LocalBrowseCheck", len=-1, rettv=0x7ffc47738030, arg=0x7ffc47737ff8, evalarg=0x7ffc477380b0, funcexe=0x7ffc47738060) at userfunc.c:1753
#17 0x000055603e513b8e in ex_call (eap=0x7ffc477381f0) at userfunc.c:5029
#18 0x000055603e3445c0 in do_one_cmd (cmdlinep=0x7ffc47738420, flags=7, cstack=0x7ffc47738500, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579010) at ex_docmd.c:2614
#19 0x000055603e3416fa in do_cmdline (cmdline=0x0, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a579010, flags=7) at ex_docmd.c:1000
#20 0x000055603e50e8b8 in call_user_func
(fp=0x7ff67a5b7bc0, argcount=1, argvars=0x7ffc47739110, rettv=0x7ffc477396d0, funcexe=
0x7ffc477394e0, selfdict=0x0) at userfunc.c:2745
#21 0x000055603e50eef3 in call_user_func_check
(fp=0x7ff67a5b7bc0, argcount=1, argvars=0x7ffc47739110, rettv=0x7ffc477396d0, funcexe=
0x7ffc477394e0, selfdict=0x0) at userfunc.c:2892
#22 0x000055603e50fd19 in call_func
(funcname=0x7ff67a598ab0 "s:LocalBrowse()", len=13, rettv=0x7ffc477396d0, argcount_in=0, argvars_in=0x7ffc47739300, funcexe=0x7ffc477394e0) at userfunc.c:3382
#23 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a598ab0 "s:LocalBrowse()", len=13, rettv=0x7ffc477396d0, arg=0x7ffc47739698, evalarg=0x55603e662940 <EVALARG_EVALUATE>, funcexe=0x7ffc477394e0) at userfunc.c:1753
#24 0x000055603e3102f3 in eval_func
(arg=0x7ffc47739698, evalarg=0x55603e662940 <EVALARG_EVALUATE>, name=0x7ff67a598734 "s:LocalBrowse()", name_len=13, rettv=0x7ffc477396d0, flags=1, basetv=0x7ffc477395a0) at eval.c:2017
#25 0x000055603e3140bf in eval_method
(arg=0x7ffc47739698, rettv=0x7ffc477396d0, evalarg=0x55603e662940 <EVALARG_EVALUATE>, verbose=1) at eval.c:3934
#26 0x000055603e317ab4 in handle_subscript
(arg=0x7ffc47739698, rettv=0x7ffc477396d0, evalarg=0x55603e662940 <EVALARG_EVALUATE>, verbose=1) at eval.c:5888
#27 0x000055603e513bf0 in ex_call (eap=0x7ffc47739890) at userfunc.c:5038
#28 0x000055603e3445c0 in do_one_cmd (cmdlinep=0x7ffc47739ac0, flags=11, cstack=0x7ffc47739ba0, fgetline=
0x0, cookie=0x0) at ex_docmd.c:2614
#29 0x000055603e3416fa in do_cmdline (cmdline=0x7ff67a5986f0 "call expand(\"%:p\")->s:LocalBrowse()", fgetline=
0x0, cookie=0x0, flags=11) at ex_docmd.c:1000
#30 0x000055603e340b8f in do_cmdline_cmd (cmd=0x7ff67a5986f0 "call expand(\"%:p\")->s:LocalBrowse()")
at ex_docmd.c:594
#31 0x000055603e31e24e in execute_common (argvars=0x7ffc4773a670, rettv=0x7ffc4773b920, arg_off=1) at evalfunc.c:3526
#32 0x000055603e3338f7 in f_win_execute (argvars=0x7ffc4773a670, rettv=0x7ffc4773b920) at evalwindow.c:713
#33 0x000055603e31c0e0 in call_internal_func
(name=0x7ff67a57fc90 "win_execute", argcount=2, argvars=0x7ffc4773a670, rettv=0x7ffc4773b920) at evalfunc.c:2539
#34 0x000055603e50fd8d in call_func
(funcname=0x7ff67a5cb610 "win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')", len=11, rettv=0x7ffc4773b920, argcount_in=2, argvars_in=0x7ffc4773a670, funcexe=0x7ffc4773a850) at userfunc.c:3400
#35 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a5cb610 "win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')", len=11, rettv=0x7ffc4773b920, arg=0x7ffc4773afa8, evalarg=0x55603e662940 <EVALARG_EVALUATE>, funcexe=0x7ffc4773a850) at userfunc.c:1753
#36 0x000055603e3102f3 in eval_func
(arg=0x7ffc4773afa8, evalarg=0x55603e662940 <EVALARG_EVALUATE>, name=0x7ff67a5cb5c7 "win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')", name_len=11, rettv=0x7ffc4773b920, flags=1, basetv=0x0) at eval.c:2017
#37 0x000055603e31374f in eval7
(arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>, want_string=0)
at eval.c:3606
#38 0x000055603e312e43 in eval7t
(arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>, want_string=0)
at eval.c:3304
#39 0x000055603e312897 in eval6
(arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>, want_string=0)
at eval.c:3096
#40 0x000055603e311fe3 in eval5 (arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>)
at eval.c:2859
#41 0x000055603e311b0f in eval4 (arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>)
at eval.c:2712
#42 0x000055603e31162f in eval3 (arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>)
at eval.c:2573
#43 0x000055603e311168 in eval2 (arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>)
at eval.c:2447
#44 0x000055603e310a34 in eval1 (arg=0x7ffc4773afa8, rettv=0x7ffc4773b920, evalarg=0x55603e662940 <EVALARG_EVALUATE>)
at eval.c:2293
#45 0x000055603e50e887 in call_user_func
(fp=0x7ff67a580030, argcount=2, argvars=0x7ffc4773b7c0, rettv=0x7ffc4773b920, funcexe=
0x7ffc4773b6c0, selfdict=0x0) at userfunc.c:2740
#46 0x000055603e50eef3 in call_user_func_check
(fp=0x7ff67a580030, argcount=2, argvars=0x7ffc4773b7c0, rettv=0x7ffc4773b920, funcexe=
0x7ffc4773b6c0, selfdict=0x0) at userfunc.c:2892
#47 0x000055603e50fd19 in call_func
(funcname=0x7ff67a5801b8 "<lambda>1", len=-1, rettv=0x7ffc4773b920, argcount_in=2, argvars_in=0x7ffc4773b7c0, funcexe=0x7ffc4773b6c0) at userfunc.c:3382
#48 0x000055603e30c5de in eval_expr_typval (expr=0x7ffc4773b9d0, argv=0x7ffc4773b7c0, argc=2, rettv=0x7ffc4773b920)
at eval.c:285
#49 0x000055603e3acc61 in filter_map_one
(tv=0x7ffc4773b910, expr=0x7ffc4773b9d0, filtermap=FILTERMAP_MAP, newtv=0x7ffc4773b920, remp=0x7ffc4773b838)
at list.c:2231
#50 0x000055603e3ad72b in filter_map (argvars=0x7ffc4773b9c0, rettv=0x7ffc4773c1b0, filtermap=FILTERMAP_MAP)
at list.c:2524
#51 0x000055603e3adabf in f_map (argvars=0x7ffc4773b9c0, rettv=0x7ffc4773c1b0) at list.c:2632
#52 0x000055603e31c68a in call_internal_method
(name=0x7ff67a57fc60 "map", argcount=1, argvars=0x7ffc4773bde0, rettv=0x7ffc4773c1b0, basetv=0x7ffc4773c080)
at evalfunc.c:2620
#53 0x000055603e50fd62 in call_func
(funcname=0x7ff67a5cbd30 "map({_, v -> win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')})", len=3, rettv=0x7ffc4773c1b0, argcount_in=1, argvars_in=0x7ffc4773bde0, funcexe=0x7ffc4773bfc0) at userfunc.c:3392
#54 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a5cbd30 "map({_, v -> win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')})", len=3, rettv=0x7ffc4773c1b0, arg=0x7ffc4773c178, evalarg=0x55603e662940 <EVALARG_EVALUATE>, funcexe=0x7ffc4773bfc0)
at userfunc.c:1753
#55 0x000055603e3102f3 in eval_func
(arg=0x7ffc4773c178, evalarg=0x55603e662940 <EVALARG_EVALUATE>, name=0x7ff67a86df9d "map({_, v -> win_execute(win_getid(v), 'call expand(\"%:p\")->s:LocalBrowse()')})", name_len=3, rettv=0x7ffc4773c1b0, flags=1, basetv=0x7ffc4773c080) at eval.c:2017
#56 0x000055603e3140bf in eval_method
(arg=0x7ffc4773c178, rettv=0x7ffc4773c1b0, evalarg=0x55603e662940 <EVALARG_EVALUATE>, verbose=1) at eval.c:3934
#57 0x000055603e317ab4 in handle_subscript
(arg=0x7ffc4773c178, rettv=0x7ffc4773c1b0, evalarg=0x55603e662940 <EVALARG_EVALUATE>, verbose=1) at eval.c:5888
#58 0x000055603e513bf0 in ex_call (eap=0x7ffc4773c370) at userfunc.c:5038
#59 0x000055603e3445c0 in do_one_cmd (cmdlinep=0x7ffc4773c5a0, flags=7, cstack=0x7ffc4773c680, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a5d34d0) at ex_docmd.c:2614
#60 0x000055603e3416fa in do_cmdline (cmdline=0x0, fgetline=
0x55603e514092 <get_func_line>, cookie=0x7ff67a5d34d0, flags=7) at ex_docmd.c:1000
#61 0x000055603e50e8b8 in call_user_func
(fp=0x7ff67a5b7f90, argcount=1, argvars=0x7ffc4773d480, rettv=0x7ffc4773d660, funcexe=
0x7ffc4773d690, selfdict=0x0) at userfunc.c:2745
#62 0x000055603e50eef3 in call_user_func_check
(fp=0x7ff67a5b7f90, argcount=1, argvars=0x7ffc4773d480, rettv=0x7ffc4773d660, funcexe=
0x7ffc4773d690, selfdict=0x0) at userfunc.c:2892
#63 0x000055603e50fd19 in call_func
(funcname=0x7ff67a59c8a0 "\200\375R15_VimEnter", len=-1, rettv=0x7ffc4773d660, argcount_in=1, argvars_in=0x7ffc4773d480, funcexe=0x7ffc4773d690) at userfunc.c:3382
#64 0x000055603e50c5d6 in get_func_tv
(name=0x7ff67a59c8a0 "\200\375R15_VimEnter", len=-1, rettv=0x7ffc4773d660, arg=0x7ffc4773d628, evalarg=0x7ffc4773d6e0, funcexe=0x7ffc4773d690) at userfunc.c:1753
#65 0x000055603e513b8e in ex_call (eap=0x7ffc4773d820) at userfunc.c:5029
#66 0x000055603e3445c0 in do_one_cmd (cmdlinep=0x7ffc4773da50, flags=7, cstack=0x7ffc4773db30, fgetline=
0x55603e2bc3da <getnextac>, cookie=0x7ffc4773e280) at ex_docmd.c:2614
#67 0x000055603e3416fa in do_cmdline (cmdline=0x0, fgetline=
0x55603e2bc3da <getnextac>, cookie=0x7ffc4773e280, flags=7) at ex_docmd.c:1000
#68 0x000055603e2bbd5a in apply_autocmds_group
(event=EVENT_VIMENTER, fname=0x7ff67a57fd20 "/etc", fname_io=0x0, force=0, group=-3, buf=0x7ff67a816940, eap=0x0)
at autocmd.c:2170
#69 0x000055603e2bb34d in apply_autocmds (event=EVENT_VIMENTER, fname=0x0, fname_io=0x0, force=0, buf=0x7ff67a816940)
at autocmd.c:1668
#70 0x000055603e5a57c6 in vim_main2 () at main.c:805
#71 0x000055603e5a4ffe in main (argc=2, argv=0x7ffc4773e408) at main.c:425
@lacygoill Yep, looks the same as the one I got.
I seem to have gotten all the way to the end of autoload/netrw.vim and still no segfault
no that is probably fine. Do I assume correctly, that the following command also crashes?
vim -u NONE -N --cmd 'com! -nargs=* NetrwKeepj keepj <args>' -c 'NetrwKeepj :1'
@chrisbra Using -fsanitize=address in CFLAGS, CXXFLAGS and LDFLAGS, right?
Search for sanitize in src/Makefile and uncomment that line (or see https://github.com/vim/vim/wiki/Debugging-Vim-Bugs) That should make it work. I don't understand why it crashes in that particular line. So the ASAN hopefully gives some insights.
I seem to have gotten all the way to the end of autoload/netrw.vim and still no segfault, but I think it's going into the actual running of the autocmds so it's going to be a lot more stepping.
Should I continue?
I stopped here:
vim --cmd 'breakadd func 8 *NetrwCommands' /etc
If you run >step, Vim crashes. Here is the backtrace right before the crash:
>bt
6 VimEnter Autocommands for "*"
5 function <SNR>15_VimEnter[16]
4 <lambda>1[1]
3 <SNR>15_LocalBrowse[32]
2 netrw#LocalBrowseCheck[26]
1 <SNR>22_NetrwBrowse[251]
->0 <SNR>22_NetrwCommands
FWIW, to build an asan-enabled Vim, usually I run this:
make clean; make distclean; sed -i '/^#\s*SANITIZER_CFLAGS.*\\$/,/^$/ s/^#// ; /^#LEAK_CFLAGS = -DEXITFREE/s/^#//' src/Makefile; make
./src/vim -Nu NONE 2>asan.log
But it doesn't work in the docker:
/usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find libasan_preinit.o: No such file or directory
/usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lasan
/usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lubsan
collect2: error: ld returned 1 exit status
link.sh: Linking failed
make[2]: *** [Makefile:2149: vim] Error 1
make[2]: Leaving directory '/root/vim/src'
make[1]: *** [Makefile:2100: reconfig] Error 2
make[1]: Leaving directory '/root/vim/src'
make: *** [Makefile:29: first] Error 2
It seems libasan is missing, but I can't install it in alpine:
# apk add libasan5
ERROR: unable to select packages:
libasan5 (no such package):
required by: world[libasan5]
looks like ASAN doesn't work in musl-libc: https://gitlab.alpinelinux.org/alpine/aports/-/issues/10304
Also, since ASAN is based on musl-libc, this might be an issue with Musl-LibC then?
no that is probably fine. Do I assume correctly, that the following command also crashes?
vim -u NONE -N --cmd 'com! -nargs=* NetrwKeepj keepj <args>' -c 'NetrwKeepj :1'
Just using this command verbatim doesn't segfault, and adding /etc to the end of it doesn't open netrw
BTW: It looks like default vim on Alpine Linux is on 8.2.3650
https://git.alpinelinux.org/aports/commit/?id=67bd6f2e6684e79a935378de1ef1c5404ef3c0bb
And that one doesn't crash?
And that one doesn't crash?
For me it crashes at the same point; at the end of the NetrwCommands() function.
But I think the issue is influenced by the OS (alpine) or by docker, because I can't reproduce on Ubuntu 20.04. And yet, :scriptnames reports the same scripts (with minor differences in the paths which shouldn't matter; e.g. /usr/bin → /usr/local/bin), in the same order, when I use this command:
mv ~/.vim/vimrc{,moved} \
&& mkdir -p /tmp/share/vim \
&& cd /tmp/share/vim \
&& curl -o vimrc https://tpaste.us/ovJr \
&& VIM=/tmp/share/vim VIMRUNTIME=/usr/local/share/vim/vim82 vim --cmd 'set rtp-=~/.vim rtp-=~/.vim/after' /etc \
&& mv ~/.vim/vimrc{moved,}
alpine uses a different libc, so that might cause it.
Alpine Linux uses a small stack for threads, smaller than other Linux distributions if I recall, which can trigger crashes not visible on other Linux distributions.
On Linux, I had used https://github.com/d99kris/stackusage to measure stack usage on various programs. It would be interesting to use it to measure stack usage on Ubuntu when trying to reproduce this issue.
BTW: It looks like default vim on Alpine Linux is on 8.2.3650
@chrisbra As I said, anything after v8.2.3584, up to master, segfaults.
Alpine Linux uses a small stack for threads, smaller than other Linux distributions if I recall, which can trigger crashes not visible on other Linux distributions.
@dpelle Even with running ulimit -s unlimited before vim /etc/, it still segfaults.
simple UAF, no asan or musl needed:
==6542== Memcheck, a memory error detector
==6542== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6542== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==6542== Command: vim /etc/
==6542== Parent PID: 1
==6542==
==6542== Invalid read of size 1
==6542== at 0x32113E: do_ucmd (usercmd.c:1778)
==6542== by 0x1C3EA5: do_one_cmd (ex_docmd.c:2606)
==6542== by 0x1C3EA5: do_cmdline (ex_docmd.c:1000)
==6542== by 0x32925D: call_user_func (userfunc.c:2745)
==6542== by 0x329803: call_user_func_check (userfunc.c:2892)
==6542== by 0x329803: call_user_func_check (userfunc.c:2858)
==6542== by 0x329D73: call_func (userfunc.c:3382)
==6542== by 0x32A381: get_func_tv (userfunc.c:1753)
==6542== by 0x32A9A4: ex_call (userfunc.c:5029)
==6542== by 0x1C388A: do_one_cmd (ex_docmd.c:2614)
==6542== by 0x1C388A: do_cmdline (ex_docmd.c:1000)
==6542== by 0x321138: do_ucmd (usercmd.c:1776)
==6542== by 0x1C3EA5: do_one_cmd (ex_docmd.c:2606)
==6542== by 0x1C3EA5: do_cmdline (ex_docmd.c:1000)
==6542== by 0x32925D: call_user_func (userfunc.c:2745)
==6542== by 0x329803: call_user_func_check (userfunc.c:2892)
==6542== by 0x329803: call_user_func_check (userfunc.c:2858)
==6542== Address 0x4c185f3 is 1,523 bytes inside a block of size 2,880 free'd
==6542== at 0x48A6FAD: realloc (vg_replace_malloc.c:1439)
==6542== by 0x14CE6B: ga_grow_inner (alloc.c:732)
==6542== by 0x31FCC9: uc_add_command (usercmd.c:966)
==6542== by 0x31FCC9: ex_command (usercmd.c:1120)
==6542== by 0x1C388A: do_one_cmd (ex_docmd.c:2614)
==6542== by 0x1C388A: do_cmdline (ex_docmd.c:1000)
==6542== by 0x32925D: call_user_func (userfunc.c:2745)
==6542== by 0x329803: call_user_func_check (userfunc.c:2892)
==6542== by 0x329803: call_user_func_check (userfunc.c:2858)
==6542== by 0x329D73: call_func (userfunc.c:3382)
==6542== by 0x32A381: get_func_tv (userfunc.c:1753)
==6542== by 0x32A9A4: ex_call (userfunc.c:5029)
==6542== by 0x1C388A: do_one_cmd (ex_docmd.c:2614)
==6542== by 0x1C388A: do_cmdline (ex_docmd.c:1000)
==6542== by 0x321138: do_ucmd (usercmd.c:1776)
==6542== by 0x1C3EA5: do_one_cmd (ex_docmd.c:2606)
==6542== by 0x1C3EA5: do_cmdline (ex_docmd.c:1000)
==6542== Block was alloc'd at
==6542== at 0x48A6FAD: realloc (vg_replace_malloc.c:1439)
==6542== by 0x14CE6B: ga_grow_inner (alloc.c:732)
==6542== by 0x31FCC9: uc_add_command (usercmd.c:966)
==6542== by 0x31FCC9: ex_command (usercmd.c:1120)
==6542== by 0x1C388A: do_one_cmd (ex_docmd.c:2614)
==6542== by 0x1C388A: do_cmdline (ex_docmd.c:1000)
==6542== by 0x2B4044: do_source (scriptfile.c:1406)
==6542== by 0x2B3090: do_in_path (scriptfile.c:330)
==6542== by 0x2B327F: do_in_path_and_pp (scriptfile.c:390)
==6542== by 0x39422E: vim_main2 (main.c:467)
==6542== by 0x401CA02: libc_start_main_stage2 (__libc_start_main.c:94)
==6542== by 0x14C666: ??? (in /usr/bin/vim)
==6542== by 0x1: ???
==6542== by 0x1FFF000EA2: ???
==6542==
==6542==
==6542== HEAP SUMMARY:
==6542== in use at exit: 3,438,699 bytes in 33,531 blocks
==6542== total heap usage: 123,304 allocs, 89,773 frees, 152,103,585 bytes allocated
==6542==
==6542== LEAK SUMMARY:
==6542== definitely lost: 0 bytes in 0 blocks
==6542== indirectly lost: 0 bytes in 0 blocks
==6542== possibly lost: 723,377 bytes in 13,804 blocks
==6542== still reachable: 2,715,322 bytes in 19,727 blocks
==6542== suppressed: 0 bytes in 0 blocks
==6542== Rerun with --leak-check=full to see details of leaked memory
==6542==
==6542== For lists of detected and suppressed errors, rerun with: -s
==6542== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
Thanks @Hello71 for reproducing it with valgrind.
The stack are truncated.
Consider using valgrind option --num-callers=50 to have deeper stacks to help understand it.
The line numbers in the stack trace do not match the current source code. Which version are you using?
Especially, what is the code at and around line 1778 in usercmd.c ?
Never mind, I can reproduce it now.
@brammool Thanks for fixing this!
However, I think the problem described in the commit message isn't exactly correct as the minimum vimrc that causes the problem (before your fix) was:
set nocompatible command A echo 'a' command B echo 'b' command C echo 'c'
Which doesn't have any recursive definition.
@brammool I haven't found any other problem, and anyway you understand the Vim code much more than I do. Thanks again for fixing this bug!