summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-06-20 19:28:14 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-20 19:28:14 +0200
commit4f8f54280fa728b7d5a63b67d02b60a3b3dce543 (patch)
tree962b41838e72571485245ed05d17dab53e0b5bfd
parent0d5e1ec37fbe75e18acba6f650c59bf91063108c (diff)
downloadvim-git-8.2.3026.tar.gz
patch 8.2.3026: Vim9: cannot set breakpoint in compiled functionv8.2.3026
Problem: Vim9: cannot set breakpoint in compiled function. Solution: Check for breakpoint when calling a function.
-rw-r--r--src/debugger.c2
-rw-r--r--src/structs.h5
-rw-r--r--src/testdir/test_debugger.vim25
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h4
-rw-r--r--src/vim9.h2
-rw-r--r--src/vim9execute.c37
7 files changed, 71 insertions, 6 deletions
diff --git a/src/debugger.c b/src/debugger.c
index b96846310..52a04907e 100644
--- a/src/debugger.c
+++ b/src/debugger.c
@@ -606,7 +606,7 @@ dbg_parsearg(
}
if (bp->dbg_type == DBG_FUNC)
- bp->dbg_name = vim_strsave(p);
+ bp->dbg_name = vim_strsave(STRNCMP(p, "g:", 2) == 0 ? p + 2 : p);
else if (here)
bp->dbg_name = vim_strsave(curbuf->b_ffname);
else if (bp->dbg_type == DBG_EXPR)
diff --git a/src/structs.h b/src/structs.h
index d62b10f37..ae2c0b850 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1629,6 +1629,11 @@ typedef struct
# endif
garray_T uf_lines; // function lines
+
+ int uf_debug_tick; // when last checked for a breakpoint in this
+ // function.
+ int uf_has_breakpoint; // TRUE when a breakpoint has been set in
+ // this function.
# ifdef FEAT_PROFILE
int uf_profiling; // TRUE when func is being profiled
int uf_prof_initialized;
diff --git a/src/testdir/test_debugger.vim b/src/testdir/test_debugger.vim
index 411909d1c..a576a8c92 100644
--- a/src/testdir/test_debugger.vim
+++ b/src/testdir/test_debugger.vim
@@ -932,6 +932,31 @@ func Test_Backtrace_DefFunction()
call delete('Xtest2.vim')
endfunc
+func Test_debug_DefFunction()
+ CheckCWD
+ let file =<< trim END
+ vim9script
+ def g:SomeFunc()
+ echo "here"
+ echo "and"
+ echo "there"
+ enddef
+ breakadd func 2 g:SomeFunc
+ END
+ call writefile(file, 'XtestDebug.vim')
+
+ let buf = RunVimInTerminal('-S XtestDebug.vim', {})
+
+ call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
+ call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
+
+ call RunDbgCmd(buf, 'cont')
+
+ call StopVimInTerminal(buf)
+ call delete('Xtest1.vim')
+ call delete('Xtest2.vim')
+endfunc
+
func Test_debug_def_function()
CheckCWD
let file =<< trim END
diff --git a/src/version.c b/src/version.c
index 961238bf9..6fe8fa498 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3026,
+/**/
3025,
/**/
3024,
diff --git a/src/vim.h b/src/vim.h
index 22fe8d5fe..e45a1de2e 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1804,9 +1804,9 @@ typedef enum {
// Keep in sync with INSTRUCTIONS().
#ifdef FEAT_PROFILE
-# define COMPILE_TYPE(ufunc) (debug_break_level > 0 ? CT_DEBUG : do_profiling == PROF_YES && (ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
+# 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)
#else
-# define COMPILE_TYPE(ufunc) debug_break_level > 0 ? CT_DEBUG : CT_NONE
+# define COMPILE_TYPE(ufunc) debug_break_level > 0 || ufunc->uf_has_breakpoint ? CT_DEBUG : CT_NONE
#endif
/*
diff --git a/src/vim9.h b/src/vim9.h
index b8c713358..97e2132a3 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -498,7 +498,7 @@ extern garray_T def_functions;
// Keep in sync with COMPILE_TYPE()
#ifdef FEAT_PROFILE
# define INSTRUCTIONS(dfunc) \
- (debug_break_level > 0 \
+ (debug_break_level > 0 || dfunc->df_ufunc->uf_has_breakpoint \
? (dfunc)->df_instr_debug \
: ((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
? (dfunc)->df_instr_prof \
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 218357a82..8b817e450 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -148,6 +148,23 @@ exe_newlist(int count, ectx_T *ectx)
}
/*
+ * If debug_tick changed check if "ufunc" has a breakpoint and update
+ * "uf_has_breakpoint".
+ */
+ static void
+update_has_breakpoint(ufunc_T *ufunc)
+{
+ if (ufunc->uf_debug_tick != debug_tick)
+ {
+ linenr_T breakpoint;
+
+ ufunc->uf_debug_tick = debug_tick;
+ breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name, 0);
+ ufunc->uf_has_breakpoint = breakpoint > 0;
+ }
+}
+
+/*
* Call compiled function "cdf_idx" from compiled code.
* This adds a stack frame and sets the instruction pointer to the start of the
* called function.
@@ -1444,6 +1461,20 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
garray_T ga;
int lnum;
+ if (ex_nesting_level > debug_break_level)
+ {
+ linenr_T breakpoint;
+
+ if (!ufunc->uf_has_breakpoint)
+ return;
+
+ // check for the next breakpoint if needed
+ breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name,
+ iptr->isn_lnum - 1);
+ if (breakpoint <= 0 || breakpoint > iptr->isn_lnum)
+ return;
+ }
+
SOURCING_LNUM = iptr->isn_lnum;
debug_context = ectx;
debug_var_count = iptr->isn_arg.number;
@@ -4206,8 +4237,7 @@ exec_instructions(ectx_T *ectx)
break;
case ISN_DEBUG:
- if (ex_nesting_level <= debug_break_level)
- handle_debug(iptr, ectx);
+ handle_debug(iptr, ectx);
break;
case ISN_SHUFFLE:
@@ -4383,6 +4413,9 @@ call_def_function(
#undef STACK_TV_VAR
#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
+ // Update uf_has_breakpoint if needed.
+ update_has_breakpoint(ufunc);
+
if (ufunc->uf_def_status == UF_NOT_COMPILED
|| ufunc->uf_def_status == UF_COMPILE_ERROR
|| (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))