Skip to content

Commit 4f8f542

Browse files
committed
patch 8.2.3026: Vim9: cannot set breakpoint in compiled function
Problem: Vim9: cannot set breakpoint in compiled function. Solution: Check for breakpoint when calling a function.
1 parent 0d5e1ec commit 4f8f542

7 files changed

Lines changed: 71 additions & 6 deletions

File tree

src/debugger.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ dbg_parsearg(
606606
}
607607

608608
if (bp->dbg_type == DBG_FUNC)
609-
bp->dbg_name = vim_strsave(p);
609+
bp->dbg_name = vim_strsave(STRNCMP(p, "g:", 2) == 0 ? p + 2 : p);
610610
else if (here)
611611
bp->dbg_name = vim_strsave(curbuf->b_ffname);
612612
else if (bp->dbg_type == DBG_EXPR)

src/structs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,11 @@ typedef struct
16291629
# endif
16301630

16311631
garray_T uf_lines; // function lines
1632+
1633+
int uf_debug_tick; // when last checked for a breakpoint in this
1634+
// function.
1635+
int uf_has_breakpoint; // TRUE when a breakpoint has been set in
1636+
// this function.
16321637
# ifdef FEAT_PROFILE
16331638
int uf_profiling; // TRUE when func is being profiled
16341639
int uf_prof_initialized;

src/testdir/test_debugger.vim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,31 @@ func Test_Backtrace_DefFunction()
932932
call delete('Xtest2.vim')
933933
endfunc
934934

935+
func Test_debug_DefFunction()
936+
CheckCWD
937+
let file =<< trim END
938+
vim9script
939+
def g:SomeFunc()
940+
echo "here"
941+
echo "and"
942+
echo "there"
943+
enddef
944+
breakadd func 2 g:SomeFunc
945+
END
946+
call writefile(file, 'XtestDebug.vim')
947+
948+
let buf = RunVimInTerminal('-S XtestDebug.vim', {})
949+
950+
call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
951+
call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
952+
953+
call RunDbgCmd(buf, 'cont')
954+
955+
call StopVimInTerminal(buf)
956+
call delete('Xtest1.vim')
957+
call delete('Xtest2.vim')
958+
endfunc
959+
935960
func Test_debug_def_function()
936961
CheckCWD
937962
let file =<< trim END

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3026,
758760
/**/
759761
3025,
760762
/**/

src/vim.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,9 +1804,9 @@ typedef enum {
18041804

18051805
// Keep in sync with INSTRUCTIONS().
18061806
#ifdef FEAT_PROFILE
1807-
# define COMPILE_TYPE(ufunc) (debug_break_level > 0 ? CT_DEBUG : do_profiling == PROF_YES && (ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
1807+
# define COMPILE_TYPE(ufunc) (debug_break_level > 0 || ufunc->uf_has_breakpoint ? CT_DEBUG : do_profiling == PROF_YES && (ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
18081808
#else
1809-
# define COMPILE_TYPE(ufunc) debug_break_level > 0 ? CT_DEBUG : CT_NONE
1809+
# define COMPILE_TYPE(ufunc) debug_break_level > 0 || ufunc->uf_has_breakpoint ? CT_DEBUG : CT_NONE
18101810
#endif
18111811

18121812
/*

src/vim9.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ extern garray_T def_functions;
498498
// Keep in sync with COMPILE_TYPE()
499499
#ifdef FEAT_PROFILE
500500
# define INSTRUCTIONS(dfunc) \
501-
(debug_break_level > 0 \
501+
(debug_break_level > 0 || dfunc->df_ufunc->uf_has_breakpoint \
502502
? (dfunc)->df_instr_debug \
503503
: ((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
504504
? (dfunc)->df_instr_prof \

src/vim9execute.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,23 @@ exe_newlist(int count, ectx_T *ectx)
147147
return OK;
148148
}
149149

150+
/*
151+
* If debug_tick changed check if "ufunc" has a breakpoint and update
152+
* "uf_has_breakpoint".
153+
*/
154+
static void
155+
update_has_breakpoint(ufunc_T *ufunc)
156+
{
157+
if (ufunc->uf_debug_tick != debug_tick)
158+
{
159+
linenr_T breakpoint;
160+
161+
ufunc->uf_debug_tick = debug_tick;
162+
breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name, 0);
163+
ufunc->uf_has_breakpoint = breakpoint > 0;
164+
}
165+
}
166+
150167
/*
151168
* Call compiled function "cdf_idx" from compiled code.
152169
* This adds a stack frame and sets the instruction pointer to the start of the
@@ -1444,6 +1461,20 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
14441461
garray_T ga;
14451462
int lnum;
14461463

1464+
if (ex_nesting_level > debug_break_level)
1465+
{
1466+
linenr_T breakpoint;
1467+
1468+
if (!ufunc->uf_has_breakpoint)
1469+
return;
1470+
1471+
// check for the next breakpoint if needed
1472+
breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name,
1473+
iptr->isn_lnum - 1);
1474+
if (breakpoint <= 0 || breakpoint > iptr->isn_lnum)
1475+
return;
1476+
}
1477+
14471478
SOURCING_LNUM = iptr->isn_lnum;
14481479
debug_context = ectx;
14491480
debug_var_count = iptr->isn_arg.number;
@@ -4206,8 +4237,7 @@ exec_instructions(ectx_T *ectx)
42064237
break;
42074238

42084239
case ISN_DEBUG:
4209-
if (ex_nesting_level <= debug_break_level)
4210-
handle_debug(iptr, ectx);
4240+
handle_debug(iptr, ectx);
42114241
break;
42124242

42134243
case ISN_SHUFFLE:
@@ -4383,6 +4413,9 @@ call_def_function(
43834413
#undef STACK_TV_VAR
43844414
#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
43854415

4416+
// Update uf_has_breakpoint if needed.
4417+
update_has_breakpoint(ufunc);
4418+
43864419
if (ufunc->uf_def_status == UF_NOT_COMPILED
43874420
|| ufunc->uf_def_status == UF_COMPILE_ERROR
43884421
|| (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))

0 commit comments

Comments
 (0)