tests fail when run with valgrind

78 views
Skip to first unread message

Dominique Pellé

unread,
Jul 24, 2016, 4:48:55 p.m.2016-07-24
to vim_dev
Hi

Using vim-7.4.2100 (and earlier), I see that all tests
pass on Linux x86_64. However, if I I enable valgrind
in src/testdir/Makefile, then tests fail:

$ make test
...
VIMRUNTIME=../../runtime; export VIMRUNTIME; valgrind --tool=memcheck
--leak-check=yes --num-callers=25 --log-file=valgrind.test_alot ../vim
-f -u unix.vim -U NONE --noplugin --not-a-term -u NONE -U NONE -S
runtest.vim test_alot.vim


From test_arglist.vim:
Executing Test_argadd()
Executing Test_argc()
Executing Test_argdelete()
Executing Test_argedit()
Executing Test_argidx()
Executing Test_arglistid()
Executing Test_argpos()
Executing Test_argument()
Executing Test_argv()
Executing Test_zero_argadd()
Executed 10 tests

From test_assert.vim:
Executing Test_assert_equal()
Executing Test_assert_exception()
Executing Test_assert_fail_fails()
Executing Test_assert_false()
Executing Test_assert_inrange()
Executing Test_assert_notequal()
Executing Test_assert_true()
Executing Test_compare_fail()
Executing Test_match()
Executing Test_notmatch()
Executing Test_user_is_happy()
Executing Test_wrong_error_type()
Executed 12 tests

From test_backspace_opt.vim:
Executing Test_backspace_option()
Executed 1 test

From test_cdo.vim:
Executing Test_cdo()
Executing Test_ldo()
Executed 2 tests

From test_channel.vim:
Executing Test_call()
Executing Test_channel_handler()
Executing Test_close_callback()
Executing Test_close_handle()
Executing Test_close_lambda()
Executing Test_close_partial()
Executing Test_collapse_buffers()
Executing Test_communicate()
Executing Test_connect_waittime()
Executing Test_exit_callback()
Executing Test_job_start_invalid()
Executing Test_nl_err_to_out_pipe()
Executing Test_nl_pipe()
Executing Test_nl_read_file()
Executing Test_nl_write_both_file()
Executing Test_nl_write_err_file()
Executing Test_nl_write_out_file()
Executing Test_open_delay()
Executing Test_open_fail()
Executing Test_out_cb()
Executing Test_out_cb_lambda()
Executing Test_out_close_cb()
Executing Test_partial_in_channel_cycle()
Executing Test_pipe_both_to_buffer()
Executing Test_pipe_err_to_buffer_name()
Executing Test_pipe_err_to_buffer_name_nomod()
Executing Test_pipe_err_to_buffer_nr()
Executing Test_pipe_from_buffer_name()
Executing Test_pipe_from_buffer_nr()
Executing Test_pipe_io_one_buffer()
Executing Test_pipe_io_two_buffers()
Executing Test_pipe_null()
Executing Test_pipe_to_buffer_json()
Executing Test_pipe_to_buffer_name()
Executing Test_pipe_to_buffer_name_nomod()
Executing Test_pipe_to_buffer_nr()
Executing Test_pipe_to_buffer_raw()
Executing Test_pipe_to_nameless_buffer()
Executing Test_raw_one_time_callback()
Executing Test_raw_pipe()
Executing Test_read_in_close_cb()
Executing Test_reuse_channel()
Executing Test_server_crash()
Executing Test_two_channels()
Executing Test_unlet_handle()
Executing Test_using_freed_memory()
Executing Test_zero_reply()
Executed 47 tests

From test_cmdline.vim:
Executing Test_complete_list()
Executing Test_complete_tab()
Executing Test_complete_wildmenu()
Executing Test_getcompletion()
Executed 4 tests

From test_cscope.vim:
Executing Test_cscopequickfix()
Executed 1 test

From test_digraph.vim:
Executing Test_digraph_cmndline()
Executing Test_digraphs()
Executing Test_digraphs_option()
Executing Test_digraphs_output()
Executing Test_loadkeymap()
Executed 5 tests

From test_farsi.vim:
Executing Test_farsi_map()
Executing Test_farsi_toggle()
Executed 2 tests

From test_gn.vim:
Executing Test_gn_command()
Executed 1 test

From test_hardcopy.vim:
Executing Test_printheader_parsing()
Executing Test_printmbfont_parsing()
Executing Test_printoptions_parsing()
Executing Test_with_syntax()
Executed 4 tests

From test_history.vim:
Executing Test_History()
Executed 1 test

From test_increment.vim:
Executing Test_normal_increment_01()
Executing Test_normal_increment_02()
Executing Test_normal_increment_03()
Executing Test_visual_increment_01()
Executing Test_visual_increment_02()
Executing Test_visual_increment_03()
Executing Test_visual_increment_04()
Executing Test_visual_increment_05()
Executing Test_visual_increment_06()
Executing Test_visual_increment_07()
Executing Test_visual_increment_08()
Executing Test_visual_increment_09()
Executing Test_visual_increment_10()
Executing Test_visual_increment_11()
Executing Test_visual_increment_12()
Executing Test_visual_increment_13()
Executing Test_visual_increment_14()
Executing Test_visual_increment_15()
Executing Test_visual_increment_16()
Executing Test_visual_increment_17()
Executing Test_visual_increment_18()
Executing Test_visual_increment_19()
Executing Test_visual_increment_20()
Executing Test_visual_increment_21()
Executing Test_visual_increment_22()
Executing Test_visual_increment_23()
Executing Test_visual_increment_24()
Executing Test_visual_increment_25()
Executing Test_visual_increment_26()
Executing Test_visual_increment_27()
Executing Test_visual_increment_28()
Executing Test_visual_increment_29()
Executing Test_visual_increment_30()
Executing Test_visual_increment_31()
Executing Test_visual_increment_32()
Executing Test_visual_increment_33()
Executing Test_visual_increment_34()
Executing Test_visual_increment_35()
Executing Test_visual_increment_36()
Executing Test_visual_increment_37()
Executing Test_visual_increment_38()
Executed 41 tests

From test_increment_dbcs.vim:
Executing Test_increment_dbcs_1()
Executed 1 test

From test_json.vim:
Executing Test_js_decode()
Executing Test_js_encode()
Executing Test_json_decode()
Executing Test_json_encode()
Executed 4 tests

From test_langmap.vim:
Executing Test_langmap()
Executed 1 test

From test_man.vim:
Executing Test_g_ft_man_open_mode()
Executing Test_nomodifiable()
Executed 2 tests

From test_matchadd_conceal.vim:
Executing Test_clearmatches()
Executing Test_default_conceal_char()
Executing Test_matchadd_and_conceallevel_3()
Executing Test_matchadd_repeat_conceal_with_syntax_off()
Executing Test_simple_matchadd()
Executing Test_simple_matchadd_and_conceal()
Executing Test_syn_and_match_conceal()
Executing Test_using_matchaddpos()
Executed 8 tests

From test_netbeans.vim:
Executing Test_nb_basic()
Flaky test failed, running it again
Executing Test_nb_basic()
Executing Test_nb_file_auth()
Executed 3 tests
1 FAILED:
Found errors in Test_nb_basic():
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 11: Expected 2 but got 130
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 12: Expected 20 but got 2
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 23: Expected '0:disconnect=1' but got '0:disconnect=0'

From test_packadd.vim:
Executing Test_colorscheme()
Executing Test_colorscheme_completion()
Executing Test_helptags()
Executing Test_packadd()
Executing Test_packadd_completion()
Executing Test_packadd_noload()
Executing Test_packloadall()
Executing Test_runtime()
Executed 8 tests

From test_perl.vim:
Executed 0 test

From test_quickfix.vim:
Executing Test_adjust_lnum()
Executing Test_browse()
Executing Test_caddbuffer_to_empty()
Executing Test_cage()
Executing Test_cbottom()
Executing Test_cbuffer()
Executing Test_cexpr()
Executing Test_cfile()
Executing Test_cgetexpr_works()
Executing Test_clist()
Executing Test_cwindow()
Executing Test_duplicate_buf()
Executing Test_efm()
Executing Test_efm1()
Executing Test_efm2()
Executing Test_efm_dirstack()
Executing Test_errortitle()
Executing Test_grep()
Executing Test_helpgrep()
Executing Test_history()
Executing Test_invalid_efm()
Executing Test_locationlist()
Executing Test_locationlist_curwin_was_closed()
Executing Test_long_lines()
Executing Test_nomem()
Executing Test_qf_title()
Executing Test_quickfix_set_list_with_act()
Executing Test_quickfix_was_changed_by_autocmd()
Executing Test_setqflist()
Executing Test_setqflist_empty_middle()
Executing Test_setqflist_empty_older()
Executing Test_switchbuf()
Executing Test_two_windows()
Executing Test_vimgreptitle()
Executed 34 tests

From test_ruby.vim:
Executed 0 test

From test_stat.vim:
Executing Test_checktime()
Executing Test_existent_directory()
Executing Test_existent_file()
Executing Test_nonexistent_file()
Executing Test_win32_symlink_dir()
Executed 5 tests

From test_syntax.vim:
Executing Test_syn_iskeyword()
Executing Test_syntax_after_reload()
Executed 2 tests

From test_textobjects.vim:
Executing Test_inner_block_with_cpo_M_left_backslash()
Executing Test_inner_block_with_cpo_M_right_backslash()
Executing Test_inner_block_without_cpo_M()
Executed 3 tests

From test_usercommands.vim:
Executing Test_cmdmods()
Executed 1 test

From test_viminfo.vim:
Executing Test_cmdline_history()
Executing Test_cmdline_history_order()
Executing Test_global_vars()
Executing Test_read_and_write()
Executing Test_viminfo_bad_syntax()
Executing Test_viminfo_encoding()
Executing Test_viminfo_file_marks()
Executing Test_viminfo_jumplist()
Executing Test_viminfo_marks()
Executing Test_viminfo_registers()
Executed 10 tests

From test_viml.vim:
Executing Test_arg_abort()
Executing Test_braces_skipped()
Executing Test_curlies()
Executing Test_defining_functions()
Executing Test_echo_and_string()
Executing Test_endwhile_function()
Executing Test_endwhile_script()
Executing Test_error_in_function()
Executing Test_error_in_script()
Executing Test_expr_parsing()
Executing Test_finish()
Executing Test_func_abort()
Executing Test_if_bar_fail()
Executing Test_if_fail()
Executing Test_if_while()
Executing Test_num64()
Executing Test_return()
Executing Test_skip()
Executing Test_type()
Executing Test_while_fail()
Executed 20 tests

From test_visual.vim:
Executing Test_block_shift_multibyte()
Executed 1 test

From test_window_id.vim:
Executing Test_win_getid()
Executed 1 test

From test_alot_latin.vim:
Executing Test_equivalence_re1()
Executing Test_equivalence_re2()
Executed 2 tests

From test_alot_utf8.vim:
Executing Test_classes_re1()
Executing Test_classes_re2()
Executing Test_equivalence_re1()
Executing Test_equivalence_re2()
Executing Test_match_using_multibyte_conceal_char()
Executing Test_strcharpart()
Executing Test_strgetchar()
Executed 7 tests

From test_alot.vim:
Executing Test_auto_partial_rebind()
Executing Test_autocmd_bufunload_with_tabnext()
Executing Test_bind_in_python()
Executing Test_bufunload()
Executing Test_caught_error_in_statusline()
Executing Test_caught_error_in_tabline()
Executing Test_color_names()
Executing Test_compare_null_dict()
Executing Test_compare_partials()
Executing Test_cursorhold_insert()
Executing Test_cursorhold_insert_ctrl_x()
Executing Test_curswant_with_autocommand()
Executing Test_cycle_partial_job()
Executing Test_cyclic_dict_arg()
Executing Test_cyclic_list_arg()
Executing Test_dict()
Executing Test_dir_delete()
Executing Test_empty_buffer()
Executing Test_equal()
Executing Test_ex_undo()
Executing Test_execute_list()
Executing Test_execute_string()
Executing Test_existing()
Executing Test_expand()
Executing Test_feedkeys_x_with_empty_string()
Executing Test_file_delete()
Executing Test_file_perm()
Executing Test_filter_map_dict_expr_funcref()
Executing Test_filter_map_dict_expr_string()
Executing Test_filter_map_list_expr_funcref()
Executing Test_filter_map_list_expr_string()
Executing Test_fnamemodify()
Executing Test_func_unref()
Executing Test_function_in_dict()
Executing Test_geeDEE()
Executing Test_gee_dee()
Executing Test_get_partial_items()
Executing Test_getreg_empty_list()
Executing Test_global_local_lispwords()
Executing Test_global_local_undolevels()
Executing Test_help_complete()
Executing Test_help_tagjump()
Executing Test_if()
Executing Test_invalid()
Executing Test_job_start_fails()
Executing Test_join_with_count()
Executing Test_lambda_fails()
Executing Test_lambda_with_filter()
Executing Test_lambda_with_map()
Executing Test_lambda_with_partial()
Executing Test_lambda_with_sort()
Executing Test_lambda_with_timer()
Executing Test_load_menu()
Executing Test_loop_over_null_list()
Executing Test_matchstrpos()
Executing Test_messages()
Executing Test_missing_attr()
Executing Test_move_cursor()
Executing Test_no_type_checking()
Executing Test_noinsert_complete()
Executing Test_non_zero_arg()
Executing Test_not_existing()
Executing Test_not_lamda()
Executing Test_oneshot()
Executing Test_option_value()
Executing Test_partial_args()
Executing Test_partial_dict()
Executing Test_partial_exists()
Executing Test_partial_implicit()
Executing Test_partial_string()
Executing Test_popup_completion_insertmode()
Executing Test_printf_64bit()
Executing Test_ptag_with_notagstack()
Executing Test_read_only()
Executing Test_recursive_delete()
Executing Test_redefine_dict_func()
Executing Test_ref_job_partial_dict()
Executing Test_reltime()
Executing Test_repeat_many()
Executing Test_repeat_three()
Executing Test_retain_partial()
Executing Test_script_function_in_dict()
Executing Test_script_function_in_dict_arg()
Executing Test_searchpos()
Executing Test_set_add()
Executing Test_set_backslash()
Executing Test_set_reg_null_list()
Executing Test_sort_default()
Executing Test_sort_float()
Executing Test_sort_nested()
Executing Test_sort_numbers()
Executing Test_sort_numeric()
Executing Test_sort_strings()
Executing Test_special_char()
Executing Test_statusline_will_be_disabled_with_error()
Executing Test_strcharpart()
Executing Test_strgetchar()
Executing Test_substitute_expr()
Executing Test_substitute_expr_arg()
Executing Test_symlink_delete()
Executing Test_symlink_dir_delete()
Executing Test_symlink_recursive_delete()
Executing Test_tabline_will_be_disabled_with_error()
Executing Test_tostring()
Executing Test_true_false_arg()
Executing Test_valid()
Executing Test_version()
Executing Test_vim_did_enter()
Executing Test_win_tab_autocmd()
Executing Test_window_cmd_cmdwin_with_vsp()
Executing Test_window_cmd_ls0_with_split()
Executing Test_window_cmd_wincmd_gf()
Executing Test_with_directories()
Executing Test_with_partial_callback()
Executing Test_with_tilde()
Executing Test_wrong_arguments()
Executed 116 tests
test61 FAILED

From test_netbeans.vim:
Found errors in Test_nb_basic():
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 11: Expected 2 but got 130
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 12: Expected 20 but got 2
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 23: Expected '0:disconnect=1' but got '0:disconnect=0'

Test results:
test61 FAILED

From test_netbeans.vim:
Found errors in Test_nb_basic():
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 11: Expected 2 but got 130
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 12: Expected 20 but got 2
function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
line 23: Expected '0:disconnect=1' but got '0:disconnect=0'
TEST FAILURE
make[1]: *** [report] Error 1
make[1]: Leaving directory `/home/pel/sb/vim/src/testdir'
make: *** [scripttests] Error 2


The test failure looks 100% reproducible with valgrind enabled.

Besides the test failure, several testdir/valgrind.* files
show memory leaks, despite having built Vim with
-DEXIT_FREE. For example, in valgrind.test_alot, I see:

==21684== Memcheck, a memory error detector
==21684== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==21684== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==21684== Command: ../vim -f -u unix.vim -U NONE --noplugin
--not-a-term -u NONE -U NONE -S runtest.vim test_alot.vim
==21684== Parent PID: 21683
==21684==
==21687==
==21687== HEAP SUMMARY:
==21687== in use at exit: 1,744,555 bytes in 6,486 blocks
==21687== total heap usage: 58,988 allocs, 52,502 frees, 93,796,076
bytes allocated
==21687==
==21687== 1 bytes in 1 blocks are possibly lost in loss record 41 of 1,017
==21687== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21687== by 0x4CE59B: lalloc (misc2.c:920)
==21687== by 0x43CB9F: get_lit_string_tv (eval.c:4984)
==21687== by 0x43CB9F: eval7 (eval.c:4253)
==21687== by 0x43CDB3: eval6 (eval.c:3977)
==21687== by 0x43D053: eval5 (eval.c:3793)
==21687== by 0x43DC94: eval4 (eval.c:3492)
==21687== by 0x43DC94: eval3 (eval.c:3409)
==21687== by 0x43DE24: eval2 (eval.c:3341)
==21687== by 0x43DE24: eval1 (eval.c:3269)
==21687== by 0x43E1CD: eval0 (eval.c:3229)
==21687== by 0x442420: ex_let (eval.c:1206)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x466CD1: do_source (ex_cmds2.c:3975)
==21687== by 0x46773B: cmd_source (ex_cmds2.c:3588)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x466CD1: do_source (ex_cmds2.c:3975)
==21687== by 0x46773B: cmd_source (ex_cmds2.c:3588)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x466CD1: do_source (ex_cmds2.c:3975)
==21687== by 0x46773B: cmd_source (ex_cmds2.c:3588)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x412179: exe_commands (main.c:2893)
==21687== by 0x412179: main (main.c:778)
==21687==
==21687== 2 bytes in 1 blocks are possibly lost in loss record 58 of 1,017
==21687== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21687== by 0x4CE59B: lalloc (misc2.c:920)
==21687== by 0x4CEE3D: alloc (misc2.c:818)
==21687== by 0x4CEE3D: vim_strsave (misc2.c:1256)
==21687== by 0x58FC11: ex_function (userfunc.c:2202)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x58DA1C: call_user_func (userfunc.c:918)
==21687== by 0x58DA1C: call_func (userfunc.c:1293)
==21687== by 0x58E455: get_func_tv (userfunc.c:483)
==21687== by 0x590A9B: ex_call (userfunc.c:2856)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x43FEC6: ex_execute (eval.c:8273)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x58DA1C: call_user_func (userfunc.c:918)
==21687== by 0x58DA1C: call_func (userfunc.c:1293)
==21687== by 0x58E455: get_func_tv (userfunc.c:483)
==21687== by 0x590A9B: ex_call (userfunc.c:2856)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x466CD1: do_source (ex_cmds2.c:3975)
==21687== by 0x46773B: cmd_source (ex_cmds2.c:3588)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x412179: exe_commands (main.c:2893)
==21687== by 0x412179: main (main.c:778)
==21687==
==21687== 5 bytes in 1 blocks are possibly lost in loss record 113 of 1,017
==21687== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21687== by 0x4CE59B: lalloc (misc2.c:920)
==21687== by 0x4CEE3D: alloc (misc2.c:818)
==21687== by 0x4CEE3D: vim_strsave (misc2.c:1256)
==21687== by 0x58C15B: get_function_args (userfunc.c:207)
==21687== by 0x58F082: ex_function (userfunc.c:1865)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x466CD1: do_source (ex_cmds2.c:3975)
==21687== by 0x46773B: cmd_source (ex_cmds2.c:3588)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x412179: exe_commands (main.c:2893)
==21687== by 0x412179: main (main.c:778)
==21687==
==21687== 6 bytes in 1 blocks are possibly lost in loss record 121 of 1,017
==21687== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21687== by 0x4CE59B: lalloc (misc2.c:920)
==21687== by 0x43CB9F: get_lit_string_tv (eval.c:4984)
==21687== by 0x43CB9F: eval7 (eval.c:4253)
==21687== by 0x43CDB3: eval6 (eval.c:3977)
==21687== by 0x43D053: eval5 (eval.c:3793)
==21687== by 0x43DC94: eval4 (eval.c:3492)
==21687== by 0x43DC94: eval3 (eval.c:3409)
==21687== by 0x43DE24: eval2 (eval.c:3341)
==21687== by 0x43DE24: eval1 (eval.c:3269)
==21687== by 0x422BA7: get_dict_tv (dict.c:577)
==21687== by 0x43CC7C: eval7 (eval.c:4268)
==21687== by 0x43CDB3: eval6 (eval.c:3977)
==21687== by 0x43D053: eval5 (eval.c:3793)
==21687== by 0x43DC94: eval4 (eval.c:3492)
==21687== by 0x43DC94: eval3 (eval.c:3409)
==21687== by 0x43DE24: eval2 (eval.c:3341)
==21687== by 0x43DE24: eval1 (eval.c:3269)
==21687== by 0x43E1CD: eval0 (eval.c:3229)
==21687== by 0x442420: ex_let (eval.c:1206)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x58DA1C: call_user_func (userfunc.c:918)
==21687== by 0x58DA1C: call_func (userfunc.c:1293)
==21687== by 0x58E455: get_func_tv (userfunc.c:483)
==21687== by 0x590A9B: ex_call (userfunc.c:2856)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x43FEC6: ex_execute (eval.c:8273)
==21687== by 0x472BCC: do_one_cmd (ex_docmd.c:2925)
==21687== by 0x472BCC: do_cmdline (ex_docmd.c:1110)
==21687== by 0x58DA1C: call_user_func (userfunc.c:918)
==21687== by 0x58DA1C: call_func (userfunc.c:1293)
==21687== by 0x58E455: get_func_tv (userfunc.c:483)
==21687== by 0x590A9B: ex_call (userfunc.c:2856)
...snip...


Regards
Dominique

Bram Moolenaar

unread,
Jul 24, 2016, 5:01:44 p.m.2016-07-24
to Dominique Pellé, vim_dev

Dominique wrote:

> Using vim-7.4.2100 (and earlier), I see that all tests
> pass on Linux x86_64. However, if I I enable valgrind
> in src/testdir/Makefile, then tests fail:
>
> $ make test
> ...
> VIMRUNTIME=../../runtime; export VIMRUNTIME; valgrind --tool=memcheck
> --leak-check=yes --num-callers=25 --log-file=valgrind.test_alot ../vim
> -f -u unix.vim -U NONE --noplugin --not-a-term -u NONE -U NONE -S
> runtest.vim test_alot.vim

[...]

> From test_netbeans.vim:
> Executing Test_nb_basic()
> Flaky test failed, running it again
> Executing Test_nb_basic()
> Executing Test_nb_file_auth()
> Executed 3 tests
> 1 FAILED:
> Found errors in Test_nb_basic():
> function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
> line 11: Expected 2 but got 130
> function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
> line 12: Expected 20 but got 2
> function RunTheTest[9]..Test_nb_basic[2]..<SNR>4_run_server[1]..RunServer[21]..Nb_basic
> line 23: Expected '0:disconnect=1' but got '0:disconnect=0'

I have seen this before, I suspect there is a race condition.

> Test results:
> test61 FAILED

This test is time sensitive. Perhaps it can be fixed by using
test_settime().

> The test failure looks 100% reproducible with valgrind enabled.
>
> Besides the test failure, several testdir/valgrind.* files
> show memory leaks, despite having built Vim with
> -DEXIT_FREE. For example, in valgrind.test_alot, I see:

test_alot is a collection of tests. Can you run them separately to
isolate the one(s) that causes the leak?


--
TIM: That is not an ordinary rabbit ... 'tis the most foul cruel and
bad-tempered thing you ever set eyes on.
ROBIN: You tit. I soiled my armour I was so scared!
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Dominique Pellé

unread,
Jul 25, 2016, 1:12:09 a.m.2016-07-25
to vim_dev
Bram Moolenaar wrote:

>> Besides the test failure, several testdir/valgrind.* files
>> show memory leaks, despite having built Vim with
>> -DEXIT_FREE. For example, in valgrind.test_alot, I see:
>
> test_alot is a collection of tests. Can you run them separately to
> isolate the one(s) that causes the leak?

I have not spent a lot of time on this yet. I'll spend more time later.
But this is enough to reproduce leaks (vim built with -DEXITFREE):

# Build vim with -DEXITFREE...
$ git diff Makefile
diff --git a/src/Makefile b/src/Makefile
index 001f87a..21fef20 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -667,7 +667,7 @@ SANITIZER_LIBS = $(SANITIZER_CFLAGS)
# Configuration is in the .ccmalloc or ~/.ccmalloc file.
# Doesn't work very well, since memory linked to from global variables
# (in libraries) is also marked as leaked memory.
-#LEAK_CFLAGS = -DEXITFREE
+LEAK_CFLAGS = -DEXITFREE
#LEAK_LIBS = -lccmalloc

#####################################################



$ ./configure --with-features=huge --enable-gui=none
$ make
$ cd src/testdir
$ valgrind --leak-check=yes ../vim -u NONE -N \
-S test_partial.vim -c 'call Test_job_start_fails()' -c q 2> log

And log file contains:

==6856== Memcheck, a memory error detector
==6856== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6856== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6856== Command: ../vim -u NONE -N -S test_partial.vim -c call\
Test_job_start_fails() -c q
==6856==
==6857==
==6857== HEAP SUMMARY:
==6857== in use at exit: 350,433 bytes in 1,828 blocks
==6857== total heap usage: 7,668 allocs, 5,840 frees, 844,057 bytes allocated
==6857==
==6857== 99 bytes in 19 blocks are possibly lost in loss record 249 of 379
==6857== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C1E2B: lalloc (misc2.c:920)
==6857== by 0x4C26CD: alloc (misc2.c:818)
==6857== by 0x4C26CD: vim_strsave (misc2.c:1256)
==6857== by 0x57AD1B: get_function_args (userfunc.c:207)
==6857== by 0x57DC42: ex_function (userfunc.c:1865)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== 192 bytes in 8 blocks are possibly lost in loss record 281 of 379
==6857== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C1E2B: lalloc (misc2.c:920)
==6857== by 0x4C2F43: alloc (misc2.c:818)
==6857== by 0x4C2F43: ga_grow (misc2.c:2009)
==6857== by 0x57AD07: get_function_args (userfunc.c:201)
==6857== by 0x57DC42: ex_function (userfunc.c:1865)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== 216 bytes in 9 blocks are possibly lost in loss record 287 of 379
==6857== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C1E2B: lalloc (misc2.c:920)
==6857== by 0x4C2F43: alloc (misc2.c:818)
==6857== by 0x4C2F43: ga_grow (misc2.c:2009)
==6857== by 0x57DF1A: ex_function (userfunc.c:2047)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== 2,448 bytes in 19 blocks are possibly lost in loss record 350 of 379
==6857== at 0x4C2CE8E: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C2EF0: ga_grow (misc2.c:2009)
==6857== by 0x57DF1A: ex_function (userfunc.c:2047)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== 6,752 bytes in 29 blocks are possibly lost in loss record 365 of 379
==6857== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C1E2B: lalloc (misc2.c:920)
==6857== by 0x57E784: ex_function (userfunc.c:2175)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== 9,265 bytes in 293 blocks are possibly lost in loss record 372 of 379
==6857== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6857== by 0x4C1E2B: lalloc (misc2.c:920)
==6857== by 0x4C26CD: alloc (misc2.c:818)
==6857== by 0x4C26CD: vim_strsave (misc2.c:1256)
==6857== by 0x57DF2A: ex_function (userfunc.c:2057)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x45C281: do_source (ex_cmds2.c:3975)
==6857== by 0x45CCEB: cmd_source (ex_cmds2.c:3588)
==6857== by 0x467D0C: do_one_cmd (ex_docmd.c:2925)
==6857== by 0x467D0C: do_cmdline (ex_docmd.c:1110)
==6857== by 0x408571: exe_commands (main.c:2893)
==6857== by 0x408571: main (main.c:778)
==6857==
==6857== LEAK SUMMARY:
==6857== definitely lost: 0 bytes in 0 blocks
==6857== indirectly lost: 0 bytes in 0 blocks
==6857== possibly lost: 18,972 bytes in 377 blocks
==6857== still reachable: 331,461 bytes in 1,451 blocks
==6857== suppressed: 0 bytes in 0 blocks
==6857== Reachable blocks (those to which a pointer was found) are not shown.
==6857== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6857==
==6857== For counts of detected and suppressed errors, rerun with: -v
==6857== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
==6856==
==6856== HEAP SUMMARY:
==6856== in use at exit: 108,951 bytes in 429 blocks
==6856== total heap usage: 7,902 allocs, 7,473 frees, 866,261 bytes allocated
==6856==
==6856== 652 (520 direct, 132 indirect) bytes in 1 blocks are
definitely lost in loss record 110 of 132
==6856== at 0x4C2AB80: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6856== by 0x526E8A8: XtMalloc (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x5277250: ??? (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x5277303: ??? (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x5277E61: _XtAppCreateShell (in
/usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x52A5C73: XtVaAppCreateShell (in
/usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x4F8533: setup_term_clip (os_unix.c:6991)
==6856== by 0x407CDE: main (main.c:611)
==6856==
==6856== 1,688 (136 direct, 1,552 indirect) bytes in 1 blocks are
definitely lost in loss record 120 of 132
==6856== at 0x4C2CE8E: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6856== by 0x550F0FD: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x550F657: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x5510F04: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x55116BB: _XlcCreateLC (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x55319CF: _XlcUtf8Loader (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x5518C4D: _XOpenLC (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x5518E7A: _XrmInitParseInfo (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x550153F: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x550490D: XrmGetStringDatabase (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x5281495: ??? (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856== by 0x5282952: _XtDisplayInitialize (in
/usr/lib/x86_64-linux-gnu/libXt.so.6.0.0)
==6856==
==6856== 46,694 (4,680 direct, 42,014 indirect) bytes in 1 blocks are
definitely lost in loss record 132 of 132
==6856== at 0x4C2CC70: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6856== by 0x54ED85A: XOpenDisplay (in
/usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==6856== by 0x4F541A: get_x11_windis (os_unix.c:1835)
==6856== by 0x4F5516: get_x11_thing (os_unix.c:1914)
==6856== by 0x4E9AC4: set_title_defaults (option.c:4127)
==6856== by 0x407C1A: main (main.c:491)
==6856==
==6856== LEAK SUMMARY:
==6856== definitely lost: 5,336 bytes in 3 blocks
==6856== indirectly lost: 43,698 bytes in 64 blocks
==6856== possibly lost: 0 bytes in 0 blocks
==6856== still reachable: 59,917 bytes in 362 blocks
==6856== suppressed: 0 bytes in 0 blocks
==6856== Reachable blocks (those to which a pointer was found) are not shown.
==6856== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6856==
==6856== For counts of detected and suppressed errors, rerun with: -v
==6856== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

Dominique Pellé

unread,
Jul 25, 2016, 5:50:35 p.m.2016-07-25
to vim_dev
About above leaks: I think that that the following comment in mch_start_job(...)
at os_unix.c:5215 explains why they happen:

os_unix.c:

5128 pid = fork(); /* maybe we should use vfork() */
5129 if (pid == -1)
5130 {
5131 /* failed to fork */
5132 goto failed;
5133 }
5134
5135 if (pid == 0)
5136 {
....
!!5214 #ifdef EXITFREE
!!5215 /* calling free_all_mem() here causes problems. Ignore valgrind
!!5216 * reporting possibly leaked memory. */
!!5217 #endif
5218 _exit(EXEC_FAILED); /* exec failed, return
failure code */
5219 }

The child process of fork(...) does not call free_all_mem().
It's probably not a real leak if it's just about not calling free_all_mem()
before exiting.

Now about the issue with test_netbeans.vim failing when tests are run
with valgrind, I still don't know why it happens.

Regards
Dominique

Dominique Pellé

unread,
Jul 27, 2016, 6:18:21 p.m.2016-07-27
to vim_dev
All test pass after patch 7.4.2108 when using valgrind. Thanks!

I still see leaks in valgrind.test_alot, Most of them come from
the child process after fork() because we don't call free_all_mem()
in the child process. But 2 leaks (below) come from the parent process.
Perhaps those 2 leaks need to be looked at. I will investigate them
this weekend:

==8980== 15 bytes in 2 blocks are definitely lost in loss record 18 of 138
==8980== at 0x4C2ABF5: malloc (vg_replace_malloc.c:299)
==8980== by 0x4E43B1: lalloc (misc2.c:920)
==8980== by 0x4E427E: alloc (misc2.c:818)
==8980== by 0x4E481E: vim_strsave (misc2.c:1256)
==8980== by 0x5F04FB: job_set_options (channel.c:4468)
==8980== by 0x449141: f_job_setoptions (evalfunc.c:6240)
==8980== by 0x440F20: call_internal_func (evalfunc.c:982)
==8980== by 0x5D0F20: call_func (userfunc.c:1314)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x5D0020: call_user_func (userfunc.c:918)
==8980== by 0x5D0E42: call_func (userfunc.c:1293)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x43D375: ex_execute (eval.c:8273)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x5D0020: call_user_func (userfunc.c:918)
==8980== by 0x5D0E42: call_func (userfunc.c:1293)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x46A465: do_source (ex_cmds2.c:3975)
==8980== by 0x469A77: cmd_source (ex_cmds2.c:3588)
==8980== by 0x4699C9: ex_source (ex_cmds2.c:3563)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x46BDDF: do_cmdline_cmd (ex_docmd.c:715)
==8980== by 0x5F65E0: exe_commands (main.c:2892)
==8980== by 0x5F39A6: main (main.c:778)
==8980==
==8980== 22 bytes in 2 blocks are definitely lost in loss record 27 of 138
==8980== at 0x4C2ABF5: malloc (vg_replace_malloc.c:299)
==8980== by 0x4E43B1: lalloc (misc2.c:920)
==8980== by 0x4E427E: alloc (misc2.c:818)
==8980== by 0x4E481E: vim_strsave (misc2.c:1256)
==8980== by 0x45395F: f_timer_start (evalfunc.c:11933)
==8980== by 0x440F20: call_internal_func (evalfunc.c:982)
==8980== by 0x5D0F20: call_func (userfunc.c:1314)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x5D0020: call_user_func (userfunc.c:918)
==8980== by 0x5D0E42: call_func (userfunc.c:1293)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x43D375: ex_execute (eval.c:8273)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x5D0020: call_user_func (userfunc.c:918)
==8980== by 0x5D0E42: call_func (userfunc.c:1293)
==8980== by 0x5CEF4F: get_func_tv (userfunc.c:483)
==8980== by 0x5D4863: ex_call (userfunc.c:2849)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x46A465: do_source (ex_cmds2.c:3975)
==8980== by 0x469A77: cmd_source (ex_cmds2.c:3588)
==8980== by 0x4699C9: ex_source (ex_cmds2.c:3563)
==8980== by 0x46FAB5: do_one_cmd (ex_docmd.c:2925)
==8980== by 0x46C7A3: do_cmdline (ex_docmd.c:1110)
==8980== by 0x46BDDF: do_cmdline_cmd (ex_docmd.c:715)
==8980== by 0x5F65E0: exe_commands (main.c:2892)
==8980== by 0x5F39A6: main (main.c:778)

Dominique

Dominique Pellé

unread,
Jul 30, 2016, 3:25:17 p.m.2016-07-30
to vim_dev
Dominique Pellé wrote:

> I still see leaks in valgrind.test_alot, Most of them come from
> the child process after fork() because we don't call free_all_mem()
> in the child process. But 2 leaks (below) come from the parent process.
> Perhaps those 2 leaks need to be looked at. I will investigate them
> this weekend:

I can reproduce one of the leaks with this minimal case:

$ cat leak.vim
let s:meow = {}
function s:meow.bite(...)
endfunction
call timer_start(50, s:meow.bite)

$ valgrind --num-callers=50 --leak-check=yes \
./vim -u NONE -N -S leak.vim -c q 2> log

And log file shows this leak:

==3006== Memcheck, a memory error detector
==3006== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3006== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==3006== Command: ./vim -u NONE -N -S leak.vim -c q
==3006==
==3006==
==3006== HEAP SUMMARY:
==3006== in use at exit: 104,857 bytes in 429 blocks
==3006== total heap usage: 7,613 allocs, 7,184 frees, 1,056,377
bytes allocated
==3006==
==3006== 2 bytes in 1 blocks are definitely lost in loss record 2 of 133
==3006== at 0x4C2ABF5: malloc (vg_replace_malloc.c:299)
==3006== by 0x4E4735: lalloc (misc2.c:920)
==3006== by 0x4E4602: alloc (misc2.c:818)
==3006== by 0x4E4BA2: vim_strsave (misc2.c:1256)
==3006== by 0x453B49: f_timer_start (evalfunc.c:11934)
==3006== by 0x44110A: call_internal_func (evalfunc.c:982)
==3006== by 0x5D1605: call_func (userfunc.c:1399)
==3006== by 0x5CF418: get_func_tv (userfunc.c:512)
==3006== by 0x5D5093: ex_call (userfunc.c:2961)
==3006== by 0x46FCC3: do_one_cmd (ex_docmd.c:2925)
==3006== by 0x46C9AF: do_cmdline (ex_docmd.c:1110)
==3006== by 0x46A671: do_source (ex_cmds2.c:3983)
==3006== by 0x469C83: cmd_source (ex_cmds2.c:3596)
==3006== by 0x469BD5: ex_source (ex_cmds2.c:3571)
==3006== by 0x46FCC3: do_one_cmd (ex_docmd.c:2925)
==3006== by 0x46C9AF: do_cmdline (ex_docmd.c:1110)
==3006== by 0x46BFEB: do_cmdline_cmd (ex_docmd.c:715)
==3006== by 0x5F71D9: exe_commands (main.c:2895)
==3006== by 0x5F4595: main (main.c:780)

Repeating the line "call timer_start(50, s:meow.bite)" n times
in leak.vim results in n leaks.

I tried this patch:

diff --git a/src/evalfunc.c b/src/evalfunc.c
index f665842..0d5e209 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -11880,14 +11880,14 @@ get_callback(typval_T *arg, partial_T **pp)
}

/*
- * Unref/free "callback" and "partial" retured by get_callback().
+ * Unref/free "callback" and "partial" returned by get_callback().
*/
void
free_callback(char_u *callback, partial_T *partial)
{
if (partial != NULL)
partial_unref(partial);
- else if (callback != NULL)
+ if (callback != NULL)
{
func_unref(callback);
vim_free(callback);

It fixes the leak in this case, but it's not correct as it causes
use of freed memory in other tests. I don't see yet how to fix it.

Dominique

Bram Moolenaar

unread,
Jul 30, 2016, 4:32:34 p.m.2016-07-30
to Dominique Pellé, vim_dev
Thanks for investigating. I recognize the problem. The callback should
not be allocated when using a partial. Now that I know where to look I
know how to fix it.

I also notice that exiting early reports leaks, probably because the
timer is still pending. Need to find a way to free them, since they are
still referenced.

--
No children may attend school with their breath smelling of "wild onions."
[real standing law in West Virginia, United States of America]
Reply all
Reply to author
Forward
0 new messages