From: zeertzjq Date: Mon, 1 Dec 2025 19:43:05 +0000 (+0000) Subject: patch 9.1.1943: Memory leak with :breakadd expr X-Git-Tag: v9.1.1943^0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a474de64dfd853eb5d3bf04f8bbd6f7d16e10c82;p=thirdparty%2Fvim.git patch 9.1.1943: Memory leak with :breakadd expr Problem: Memory leak with :breakadd expr Solution: Free debug_oldval and debug_newval before assigning to them. Verify the existing (though confusing) :breakadd expr behavior (zeertzjq). It seems that :breakadd expr doesn't work as documented at all. This PR only fixes the memory leak. The tests are for the existing behavior. closes: #18844 Signed-off-by: zeertzjq Signed-off-by: Christian Brabandt --- diff --git a/src/debugger.c b/src/debugger.c index 97d54c4394..f553a8e6a6 100644 --- a/src/debugger.c +++ b/src/debugger.c @@ -1111,8 +1111,10 @@ debuggy_find( { if (bp->dbg_val == NULL) { + vim_free(debug_oldval); debug_oldval = typval_tostring(NULL, TRUE); bp->dbg_val = tv; + vim_free(debug_newval); debug_newval = typval_tostring(bp->dbg_val, TRUE); line = TRUE; } @@ -1129,10 +1131,12 @@ debuggy_find( typval_T *v; line = TRUE; + vim_free(debug_oldval); debug_oldval = typval_tostring(bp->dbg_val, TRUE); // Need to evaluate again, typval_compare() overwrites // "tv". v = eval_expr_no_emsg(bp); + vim_free(debug_newval); debug_newval = typval_tostring(v, TRUE); free_tv(bp->dbg_val); bp->dbg_val = v; @@ -1142,7 +1146,9 @@ debuggy_find( } else if (bp->dbg_val != NULL) { + vim_free(debug_oldval); debug_oldval = typval_tostring(bp->dbg_val, TRUE); + vim_free(debug_newval); debug_newval = typval_tostring(NULL, TRUE); free_tv(bp->dbg_val); bp->dbg_val = NULL; diff --git a/src/testdir/test_debugger.vim b/src/testdir/test_debugger.vim index 264420998e..aa014c4342 100644 --- a/src/testdir/test_debugger.vim +++ b/src/testdir/test_debugger.vim @@ -361,34 +361,73 @@ func Test_Debugger_breakadd() endfunc " Test for expression breakpoint set using ":breakadd expr " +" FIXME: This doesn't seem to work as documented. The breakpoint is not +" triggered until the next function call. func Test_Debugger_breakadd_expr() CheckCWD let lines =<< trim END + func Foo() + eval 1 + eval 2 + endfunc + let g:Xtest_var += 1 + call Foo() + let g:Xtest_var += 1 + call Foo() END - call writefile(lines, 'XdebugBreakExpr.vim', 'D') + call writefile(lines, 'XbreakExpr.vim', 'D') " Start Vim in a terminal - let buf = RunVimInTerminal('XdebugBreakExpr.vim', {}) + let buf = RunVimInTerminal('XbreakExpr.vim', {}) call s:RunDbgCmd(buf, ':let g:Xtest_var = 10') call s:RunDbgCmd(buf, ':breakadd expr g:Xtest_var') - call s:RunDbgCmd(buf, ':source %') let expected =<< trim eval END Oldval = "10" Newval = "11" - {fnamemodify('XdebugBreakExpr.vim', ':p')} - line 1: let g:Xtest_var += 1 + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 1: eval 1 END call s:RunDbgCmd(buf, ':source %', expected) - call s:RunDbgCmd(buf, 'cont') let expected =<< trim eval END Oldval = "11" Newval = "12" - {fnamemodify('XdebugBreakExpr.vim', ':p')} - line 1: let g:Xtest_var += 1 + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 1: eval 1 + END + call s:RunDbgCmd(buf, 'cont', expected) + call s:RunDbgCmd(buf, 'cont') + + " Check the behavior without the g: prefix. + " FIXME: The Oldval and Newval don't look right here. + call s:RunDbgCmd(buf, ':breakdel *') + call s:RunDbgCmd(buf, ':breakadd expr Xtest_var') + let expected =<< trim eval END + Oldval = "13" + Newval = "(does not exist)" + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 1: eval 1 END call s:RunDbgCmd(buf, ':source %', expected) + let expected =<< trim eval END + {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo + line 2: eval 2 + END + call s:RunDbgCmd(buf, 'cont', expected) + let expected =<< trim eval END + Oldval = "14" + Newval = "(does not exist)" + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 1: eval 1 + END + call s:RunDbgCmd(buf, 'cont', expected) + let expected =<< trim eval END + {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo + line 2: eval 2 + END + call s:RunDbgCmd(buf, 'cont', expected) + call s:RunDbgCmd(buf, 'cont') call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c index 81e8cf3b7a..d347aac56c 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1943, /**/ 1942, /**/