vim (все полнофункциональные варианты, не только vim-console) падает при выполнении примера из ":help self": :function Mylen() dict : return len(self.data) :endfunction :let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")} :echo mydict.len() #0 0x00002aaaacd333a5 in raise () from /lib64/libc.so.6 #1 0x00002aaaacd34730 in abort () from /lib64/libc.so.6 #2 0x00002aaaacd68ebb in __fsetlocking () from /lib64/libc.so.6 #3 0x00002aaaacdd04ff in __chk_fail () from /lib64/libc.so.6 #4 0x0000000000457a64 in call_func (name=0x857e90 "Mylen", len=Variable "len" is not available. ) at eval.c:19832 #5 0x000000000045a8dc in get_func_tv (name=0x857e90 "Mylen", len=5, rettv=0x7fff452d7cd0, arg=0x7fff452d7ce8, firstline=494, lastline=494, doesrange=0x7fff452d77fc, evaluate=1, selfdict=0x921410) at eval.c:7411 #6 0x000000000045aacb in handle_subscript (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1, verbose=1) at eval.c:17185 #7 0x000000000045be48 in eval7 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:4701 #8 0x000000000045c6a4 in eval6 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:4442 #9 0x000000000045927f in eval5 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:4311 #10 0x00000000004594f6 in eval4 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:4043 #11 0x0000000000459c24 in eval3 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:3955 #12 0x0000000000459d74 in eval1 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, evaluate=1) at eval.c:3884 #13 0x000000000045a042 in ex_echo (eap=0x7fff452d7e50) at eval.c:18150 #14 0x000000000047d974 in do_one_cmd (cmdlinep=0x7fff452d8068, sourcing=0, cstack=0x7fff452d8070, fgetline=0x48bad0 <getexline>, cookie=0x0) at ex_docmd.c:2616 #15 0x000000000047eda9 in do_cmdline (cmdline=Variable "cmdline" is not available. ) at ex_docmd.c:1098 #16 0x00000000004e8352 in nv_colon (cap=0x7fff452d85b0) at normal.c:5161 #17 0x00000000004ea9d3 in normal_cmd (oap=0x7fff452d8650, toplevel=1) at normal.c:1136 #18 0x00000000004affbf in main_loop (cmdwin=0, noexmode=0) at main.c:1154 #19 0x00000000004b301a in main (argc=Variable "argc" is not available. ) at main.c:934 При сборке vim обнаружилось предупреждение: eval.c: In function 'call_func': eval.c:19832: warning: call to __builtin___strcpy_chk will always overflow destination buffer Ситуация следующая: тип dictitem_T объявлен как: /* * Structure to hold an item of a Dictionary. * Also used for a variable. * The key is copied into "di_key" to avoid an extra alloc/free for it. */ struct dictitem_S { typval_T di_tv; /* type and value of the variable */ char_u di_flags; /* flags (only used for variable) */ char_u di_key[1]; /* key (actually longer!) */ }; typedef struct dictitem_S dictitem_T; При этом в eval.c:call_user_func() имеется следующий код: funccall_T fc; dictitem_T *v; char_u *name; ... /* Set l:self to "selfdict". Use "name" to avoid a warning from * some compiler that checks the destination size. */ v = &fc.fixvar[fixvar_idx++].var; name = v->di_key; STRCPY(name, "self"); Однако даже использование промежуточной переменной name не помогает скрыть от компилятора то, что копирование происходит в поле di_key, которое объявлено как массив из 1 элемента. Вероятно, играет роль и то, что структура funccall_S определена весьма специфическим образом: struct funccall_S { ... struct /* fixed variables for arguments */ { dictitem_T var; /* variable (without room for name) */ char_u room[VAR_SHORT_LEN]; /* room for the name */ } fixvar[FIXVAR_CNT]; ... }; Т.е., в данном случае код написан с расчётом на то, что var.di_name будет переполнено с залезанием в room.
Патч из OpenSUSE нашёл, заслал проблему в обстрём, посмотрим что будет...
На самом деле это, конечно, не -fstack-protector, а -D_FORTIFY_SOURCE=2.
Апстрим послал меня чинить gcc и ставить релиз glibc вместо "unfinished and contains bugs" снапшота. В следующей сборке приложу патч, посмотрим что будет...
Fixed in 4:7.0.218-alt1