vim9script segfault in vim9execute

28 views
Skip to first unread message

Christian Brabandt

unread,
May 8, 2021, 5:30:35 AM5/8/21
to vim...@vim.org
Trying to convert vim-airline to vim9 script, I see the following crash:

I see the following error before Vim crashes and most likely there is a
problem with my newly created vim9 script, but I don't think Vim should
crash then. I guess the error makes the instruction pointer null.

Error detected while processing BufWinEnter Autocommands for "*"..function <SNR>37_on_window_changed[22]..<SNR>37_init[29]..<SNR>37_on_colorscheme_changed[5]..airline#switch_matching_theme[18]..BufWinEnter Autocommands for "*"..function
<SNR>37_on_window_changed[22]..<SNR>37_init[29]..<SNR>37_on_colorscheme_changed[5]..airline#switch_matching_theme[13]..airline#switch_theme[35]..airline#load_theme:
line 14:
E1091: Function is not compiled: airline#highlighter#load_theme
Error detected while processing BufWinEnter Autocommands for "*"..function <SNR>37_on_window_changed[22]..<SNR>37_init[29]..<SNR>37_on_colorscheme_changed:
line 5:
E171: Missing :endif
Error detected while processing BufWinEnter Autocommands for "*"..function <SNR>37_on_window_changed[22]..<SNR>37_init:
line 29:
E171: Missing :endif
Press ENTER or type command to continue

Sorry, I haven't tried to come to a minimal example, because vim-airline
is such a complex beast with many different files :/

Nevertheless I attach the backtrace.

Best,
Christian
--
Das höchste Glück des Lebens besteht in der Überzeugung, geliebt zu
werden.
-- Victor Marie Hugo
gdb.txt

Christian Brabandt

unread,
May 8, 2021, 5:40:27 AM5/8/21
to vim...@vim.org

On Sa, 08 Mai 2021, Christian Brabandt wrote:

> Program received signal SIGSEGV, Segmentation fault.
> 0x000055555581acf5 in exec_instructions (ectx=0x7fffffff2da0) at vim9execute.c:1367
> 1367 switch (iptr->isn_type)

Hm, the log does not show, iptr is null.

BTW: I also compiled an asan version, but even so I did export
ASAN_OPTIONS="print_stacktrace=1 log_path=asan.log", I did not get an
asan report :/


Best,
Christian
--
Wäre Chuck Norris Spartaner, würde der Film nicht "300" sondern "1"
heißen.

Dominique Pellé

unread,
May 8, 2021, 6:06:13 AM5/8/21
to vim_dev, vim-dev
Christian Brabandt <cbl...@256bit.org> wrote:

> On Sa, 08 Mai 2021, Christian Brabandt wrote:
>
> > Program received signal SIGSEGV, Segmentation fault.
> > 0x000055555581acf5 in exec_instructions (ectx=0x7fffffff2da0) at vim9execute.c:1367
> > 1367 switch (iptr->isn_type)
>
> Hm, the log does not show, iptr is null.
>
> BTW: I also compiled an asan version, but even so I did export
> ASAN_OPTIONS="print_stacktrace=1 log_path=asan.log", I did not get an
> asan report :/

According to https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
The various options should be separated by a colon, not a space.

Try putting also full path such as log_path=/tmp/asan.log
otherwise if vim changes the current directory, it may be hard
to know where asan.log is. Or run ./vim 2> log asan.log.

Consider also trying with valgrind.

Dominique

Christian Brabandt

unread,
May 8, 2021, 6:37:19 AM5/8/21
to vim_dev, vim-dev

On Sa, 08 Mai 2021, Dominique Pellé wrote:

> Christian Brabandt <cbl...@256bit.org> wrote:
>
> > On Sa, 08 Mai 2021, Christian Brabandt wrote:
> >
> > > Program received signal SIGSEGV, Segmentation fault.
> > > 0x000055555581acf5 in exec_instructions (ectx=0x7fffffff2da0) at vim9execute.c:1367
> > > 1367 switch (iptr->isn_type)
> >
> > Hm, the log does not show, iptr is null.
> >
> > BTW: I also compiled an asan version, but even so I did export
> > ASAN_OPTIONS="print_stacktrace=1 log_path=asan.log", I did not get an
> > asan report :/
>
> According to https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
> The various options should be separated by a colon, not a space.

Ah, the comment in the Makefile is wrong then. Well, it is not helpful:
=================================================================
==150796==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 367872 byte(s) in 102 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a843aa49 (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x174a49)

Direct leak of 23728 byte(s) in 26 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a839b4ad in _PyObject_GC_Malloc (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0xd54ad)

Direct leak of 2064 byte(s) in 32 object(s) allocated from:
#0 0x7fd2a9c021f8 in __interceptor_realloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xaa1f8)
#1 0x7fd2a844f006 in PyList_Append (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x189006)

Direct leak of 2002 byte(s) in 3 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a842f413 in PyString_FromStringAndSize (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x169413)

Direct leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a845025f in PyList_New (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x18a25f)

Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a845025f in PyList_New (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x18a25f)
#2 0x7ffca24f910f ([stack]+0x2510f)

Indirect leak of 10384 byte(s) in 11 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a839b4ad in _PyObject_GC_Malloc (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0xd54ad)

Indirect leak of 4089 byte(s) in 6 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a842f298 in PyString_FromString (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x169298)

Indirect leak of 2090 byte(s) in 3 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a8421fab (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x15bfab)

Indirect leak of 1346 byte(s) in 2 object(s) allocated from:
#0 0x7fd2a9c01e8f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xa9e8f)
#1 0x7fd2a842f413 in PyString_FromStringAndSize (/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x169413)

SUMMARY: AddressSanitizer: 413615 byte(s) leaked in 187 allocation(s).

I suppose those are not relevant.

But ./vim 2>asan.log at least shows this:
vim9execute.c:1367:14: runtime error: member access within null pointer of type 'struct isn_T'


> Try putting also full path such as log_path=/tmp/asan.log
> otherwise if vim changes the current directory, it may be hard
> to know where asan.log is. Or run ./vim 2> log asan.log.
>
> Consider also trying with valgrind.

Ah yes, forgot about it. Attached.

(I should probably compile without python).

Best,
Christian
--
Man kann seiner eigenen Zeit nicht böse sein, ohne selbst Schaden zu
nehmen.
-- Robert Musil
valgrind.log

Christian Brabandt

unread,
May 8, 2021, 7:49:58 AM5/8/21
to vim...@vim.org

On Sa, 08 Mai 2021, Christian Brabandt wrote:

> Trying to convert vim-airline to vim9 script, I see the following crash:
>
> I see the following error before Vim crashes and most likely there is a
> problem with my newly created vim9 script, but I don't think Vim should
> crash then. I guess the error makes the instruction pointer null.
>

I think the crash was caused by this function:

,----
| def airline#highlighter#exec(group: string, clrs: list<any>): void
| [...]
| if old_hi != new_hi || !s:hl_group_exists(group)
| var cmd = ''
| cmd = printf('hi %s%s', group, s:GetHiCmd(colors))
| try
| :exe cmd
| catch /^Vim\%((\a\+)\)\=:E421:/
| group=matchstr(v:exception, '\w\+\ze=')
| var color=matchstr(v:exception, '=\zs\w\+')
| let cmd=substitute(cmd, color, 'grey', 'g')
| exe cmd
| airline#util#warning('color definition for group ' .. group .. ' not found, using grey as fallback')
| catch
| airline#util#warning('Error when running command: '. cmd)
| endtry
| [...]
| endif
| enddef
`----

I think the crucial part is the catch section, trying to parse
v:exception and trying to reuse the function argument name group.

I have that part now rewritten as this:

,----
| catch /^Vim\%((\a\+)\)\=:E421:/
| var grp = matchstr(v:exception, '\w\+\ze=')
| var clr = matchstr(v:exception, '=\zs\w\+')
| cmd = substitute(cmd, clr, 'grey', 'g')
| :exe cmd
`----

and at least it is not crashing anymore.


Best,
Christian
--
Wir haben verlernt, die Augen auf etwas ruhen zu lassen. Deshalb
erkennen wir so wenig.
-- Jean Giono

Dominique Pellé

unread,
May 8, 2021, 8:04:23 AM5/8/21
to vim_dev, vim-dev
Christian Brabandt wrote:

> But ./vim 2>asan.log at least shows this:
> vim9execute.c:1367:14: runtime error: member access within null pointer of type 'struct isn_T'

That's an error reported by ubsan (undefined behavior
sanitizer (not asan, address sanitizer). You either built
with ubsan only (which by default does not abort on errors)
or you built with ubsan & asan at the same time.

ubsan errors are generally less severe than asan errors.
Netheless, they are still bugs which should be fixed.

> > Try putting also full path such as log_path=/tmp/asan.log
> > otherwise if vim changes the current directory, it may be hard
> > to know where asan.log is. Or run ./vim 2> log asan.log.
> >
> > Consider also trying with valgrind.
>
> Ah yes, forgot about it. Attached.
>
> (I should probably compile without python).

Yes, Python causes annoying false errors with valgrind,
unless you build your own python library using
"configure --without-pymalloc".
The easiest workaround to silence them is to build vim
without python if that's possible in your case.


Dominique

Bram Moolenaar

unread,
May 8, 2021, 8:36:03 AM5/8/21
to vim...@googlegroups.com, Christian Brabandt, vim...@vim.org
Is that really using a single dot for string concatenation? That should
fail during compilation. Oh, there also is a :let there, so this can't
possibly be compiled. Maybe the problem is at the caller of this
function, when compilation produces an error?

> I have that part now rewritten as this:
>
> ,----
> | catch /^Vim\%((\a\+)\)\=:E421:/
> | var grp = matchstr(v:exception, '\w\+\ze=')
> | var clr = matchstr(v:exception, '=\zs\w\+')
> | cmd = substitute(cmd, clr, 'grey', 'g')
> | :exe cmd
> `----
>
> and at least it is not crashing anymore.


I cannot guess why the instruction is NULL. Easiest would be to run Vim
in gdb and it should stop when it happens. Then you can look around,
such as the value of "ectx->ec_iidx".

You can also use ch_log() to write some events to a log file (started
with ch_logfile()) in case it's timing sensitive.

And you could disassemble that function:

:disass airline#highlighter#exec

I hope you can find a reproduction case, so we can have a test for this
failure.

--
Hear about the guy who played a blank tape at full blast?
The mime next door went nuts.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages