To: vim_dev@googlegroups.com Subject: Patch 8.2.0489 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0489 Problem: Vim9: memory leaks. Solution: Free memory in the right place. Add hints for using asan. Files: src/vim9compile.c, src/testdir/lsan-suppress.txt, src/Makefile *** ../vim-8.2.0488/src/vim9compile.c 2020-03-31 23:32:27.042315928 +0200 --- src/vim9compile.c 2020-04-01 16:29:45.468391124 +0200 *************** *** 3500,3506 **** if (cmdidx == CMD_const) { emsg(_(e_const_option)); ! return NULL; } if (is_decl) { --- 3500,3506 ---- if (cmdidx == CMD_const) { emsg(_(e_const_option)); ! goto theend; } if (is_decl) { *************** *** 3513,3519 **** { // cannot happen? emsg(_(e_letunexp)); ! return NULL; } cc = *p; *p = NUL; --- 3513,3519 ---- { // cannot happen? emsg(_(e_letunexp)); ! goto theend; } cc = *p; *p = NUL; *************** *** 3522,3528 **** if (opt_type == -3) { semsg(_(e_unknown_option), arg); ! return NULL; } if (opt_type == -2 || opt_type == 0) type = &t_string; --- 3522,3528 ---- if (opt_type == -3) { semsg(_(e_unknown_option), arg); ! goto theend; } if (opt_type == -2 || opt_type == 0) type = &t_string; *************** *** 3543,3549 **** if (!valid_yank_reg(arg[1], TRUE)) { emsg_invreg(arg[1]); ! return FAIL; } dest = dest_reg; if (is_decl) --- 3543,3549 ---- if (!valid_yank_reg(arg[1], TRUE)) { emsg_invreg(arg[1]); ! goto theend; } dest = dest_reg; if (is_decl) *************** *** 3994,3999 **** --- 3994,4016 ---- } /* + * Free the current scope and go back to the outer scope. + */ + static void + drop_scope(cctx_T *cctx) + { + scope_T *scope = cctx->ctx_scope; + + if (scope == NULL) + { + iemsg("calling drop_scope() without a scope"); + return; + } + cctx->ctx_scope = scope->se_outer; + vim_free(scope); + } + + /* * Evaluate an expression that is a constant: * has(arg) * *************** *** 4412,4418 **** return NULL; } ifscope = &scope->se_u.se_if; - cctx->ctx_scope = scope->se_outer; unwind_locals(cctx, scope->se_local_count); if (scope->se_u.se_if.is_if_label >= 0) --- 4429,4434 ---- *************** *** 4425,4431 **** compile_fill_jump_to_end(&ifscope->is_end_label, cctx); cctx->ctx_skip = FALSE; ! vim_free(scope); return arg; } --- 4441,4447 ---- compile_fill_jump_to_end(&ifscope->is_end_label, cctx); cctx->ctx_skip = FALSE; ! drop_scope(cctx); return arg; } *************** *** 4486,4510 **** --- 4502,4536 ---- // Reserve a variable to store the loop iteration counter. loop_idx = reserve_local(cctx, (char_u *)"", 0, FALSE, &t_number); if (loop_idx < 0) + { + drop_scope(cctx); return NULL; + } // Reserve a variable to store "var" var_idx = reserve_local(cctx, arg, varlen, FALSE, &t_any); if (var_idx < 0) + { + drop_scope(cctx); return NULL; + } generate_STORENR(cctx, loop_idx, -1); // compile "expr", it remains on the stack until "endfor" arg = p; if (compile_expr1(&arg, cctx) == FAIL) + { + drop_scope(cctx); return NULL; + } // now we know the type of "var" vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; if (vartype->tt_type != VAR_LIST) { emsg(_("E1024: need a List to iterate over")); + drop_scope(cctx); return NULL; } if (vartype->tt_member->tt_type != VAR_UNKNOWN) *** ../vim-8.2.0488/src/testdir/lsan-suppress.txt 2020-03-30 19:13:24.977239954 +0200 --- src/testdir/lsan-suppress.txt 2020-04-01 16:30:50.192114902 +0200 *************** *** 9,11 **** --- 9,12 ---- leak:libperl.so.* leak:libpython*.so.* leak:libruby*.so.* + leak:libxcb*.so.* *** ../vim-8.2.0488/src/Makefile 2020-03-24 21:41:38.023535429 +0100 --- src/Makefile 2020-04-01 16:32:11.583770563 +0200 *************** *** 691,699 **** # Uncomment one of the next two lines to compile Vim with the ! # address sanitizer or with the undefined sanitizer. Works with gcc and # clang. May make Vim twice as slow. Errors reported on stderr. # More at: https://code.google.com/p/address-sanitizer/ #SANITIZER_CFLAGS = -g -O0 -fsanitize=address -fno-omit-frame-pointer #SANITIZER_CFLAGS = -g -O0 -fsanitize=undefined -fno-omit-frame-pointer SANITIZER_LIBS = $(SANITIZER_CFLAGS) --- 691,702 ---- # Uncomment one of the next two lines to compile Vim with the ! # address sanitizer (asan) or with the undefined sanitizer. Works with gcc and # clang. May make Vim twice as slow. Errors reported on stderr. # More at: https://code.google.com/p/address-sanitizer/ + # Useful environment variables: + # $ export ASAN_OPTIONS="print_stacktrace=1 log_path=asan" + # $ export LSAN_OPTIONS="suppressions=$cwd/testdir/lsan-suppress.txt" #SANITIZER_CFLAGS = -g -O0 -fsanitize=address -fno-omit-frame-pointer #SANITIZER_CFLAGS = -g -O0 -fsanitize=undefined -fno-omit-frame-pointer SANITIZER_LIBS = $(SANITIZER_CFLAGS) *** ../vim-8.2.0488/src/version.c 2020-03-31 23:32:27.046315914 +0200 --- src/version.c 2020-04-01 16:31:29.243949296 +0200 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 489, /**/ -- 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 -- Bram@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 ///