mirror of
https://github.com/neovim/neovim.git
synced 2025-09-25 04:28:33 +00:00
vim-patch:8.2.3417: Vim9: a failing debug expression aborts script sourcing
Problem: Vim9: a failing debug expression aborts script sourcing.
Solution: Do not let expression failure abort script sourcing. (closes vim/vim#8848)
072f1c6888
Vim9script is N/A, exclude Test_Debugger_breakadd_expr.
Move debuggy struct to before generated header inclusion so
eval_expr_restore prototype works.
Add CheckRunVimInTerminal to Test_Debugger_breakadd.
Cherry-pick Test_Debugger_breakadd changes from v8.2.1440, v8.2.1736.
This commit is contained in:
@@ -27,6 +27,19 @@ static bool debug_greedy = false;
|
|||||||
static char *debug_oldval = NULL; // old and newval for debug expressions
|
static char *debug_oldval = NULL; // old and newval for debug expressions
|
||||||
static char *debug_newval = NULL;
|
static char *debug_newval = NULL;
|
||||||
|
|
||||||
|
/// The list of breakpoints: dbg_breakp.
|
||||||
|
/// This is a grow-array of structs.
|
||||||
|
struct debuggy {
|
||||||
|
int dbg_nr; ///< breakpoint number
|
||||||
|
int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR
|
||||||
|
char_u *dbg_name; ///< function, expression or file name
|
||||||
|
regprog_T *dbg_prog; ///< regexp program
|
||||||
|
linenr_T dbg_lnum; ///< line number in function or file
|
||||||
|
int dbg_forceit; ///< ! used
|
||||||
|
typval_T *dbg_val; ///< last result of watchexpression
|
||||||
|
int dbg_level; ///< stored nested level for expr
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "debugger.c.generated.h"
|
# include "debugger.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -429,19 +442,6 @@ bool dbg_check_skipped(exarg_T *eap)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The list of breakpoints: dbg_breakp.
|
|
||||||
/// This is a grow-array of structs.
|
|
||||||
struct debuggy {
|
|
||||||
int dbg_nr; ///< breakpoint number
|
|
||||||
int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR
|
|
||||||
char_u *dbg_name; ///< function, expression or file name
|
|
||||||
regprog_T *dbg_prog; ///< regexp program
|
|
||||||
linenr_T dbg_lnum; ///< line number in function or file
|
|
||||||
int dbg_forceit; ///< ! used
|
|
||||||
typval_T *dbg_val; ///< last result of watchexpression
|
|
||||||
int dbg_level; ///< stored nested level for expr
|
|
||||||
};
|
|
||||||
|
|
||||||
static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL };
|
static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL };
|
||||||
#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
|
#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
|
||||||
#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
|
#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
|
||||||
@@ -453,6 +453,26 @@ static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL };
|
|||||||
#define DBG_FILE 2
|
#define DBG_FILE 2
|
||||||
#define DBG_EXPR 3
|
#define DBG_EXPR 3
|
||||||
|
|
||||||
|
/// Evaluate the "bp->dbg_name" expression and return the result.
|
||||||
|
/// Restore the got_int and called_emsg flags.
|
||||||
|
static typval_T *eval_expr_restore(struct debuggy *const bp)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
const int prev_called_emsg = called_emsg;
|
||||||
|
const int prev_did_emsg = did_emsg;
|
||||||
|
|
||||||
|
got_int = false;
|
||||||
|
typval_T *const tv = eval_expr(bp->dbg_name);
|
||||||
|
|
||||||
|
// Evaluating the expression should not result in breaking the sequence of
|
||||||
|
// commands.
|
||||||
|
got_int = false;
|
||||||
|
called_emsg = prev_called_emsg;
|
||||||
|
did_emsg = prev_did_emsg;
|
||||||
|
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
|
/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
|
||||||
/// in the entry just after the last one in dbg_breakp. Note that "dbg_name"
|
/// in the entry just after the last one in dbg_breakp. Note that "dbg_name"
|
||||||
/// is allocated.
|
/// is allocated.
|
||||||
@@ -515,7 +535,7 @@ static int dbg_parsearg(char_u *arg, garray_T *gap)
|
|||||||
bp->dbg_name = vim_strsave(curbuf->b_ffname);
|
bp->dbg_name = vim_strsave(curbuf->b_ffname);
|
||||||
} else if (bp->dbg_type == DBG_EXPR) {
|
} else if (bp->dbg_type == DBG_EXPR) {
|
||||||
bp->dbg_name = vim_strsave(p);
|
bp->dbg_name = vim_strsave(p);
|
||||||
bp->dbg_val = eval_expr(bp->dbg_name);
|
bp->dbg_val = eval_expr_restore(bp);
|
||||||
} else {
|
} else {
|
||||||
// Expand the file name in the same way as do_source(). This means
|
// Expand the file name in the same way as do_source(). This means
|
||||||
// doing it twice, so that $DIR/file gets expanded when $DIR is
|
// doing it twice, so that $DIR/file gets expanded when $DIR is
|
||||||
@@ -771,10 +791,7 @@ debuggy_find(
|
|||||||
} else if (bp->dbg_type == DBG_EXPR) {
|
} else if (bp->dbg_type == DBG_EXPR) {
|
||||||
bool line = false;
|
bool line = false;
|
||||||
|
|
||||||
prev_got_int = got_int;
|
typval_T *const tv = eval_expr_restore(bp);
|
||||||
got_int = false;
|
|
||||||
|
|
||||||
typval_T *tv = eval_expr(bp->dbg_name);
|
|
||||||
if (tv != NULL) {
|
if (tv != NULL) {
|
||||||
if (bp->dbg_val == NULL) {
|
if (bp->dbg_val == NULL) {
|
||||||
debug_oldval = typval_tostring(NULL);
|
debug_oldval = typval_tostring(NULL);
|
||||||
@@ -787,7 +804,7 @@ debuggy_find(
|
|||||||
line = true;
|
line = true;
|
||||||
debug_oldval = typval_tostring(bp->dbg_val);
|
debug_oldval = typval_tostring(bp->dbg_val);
|
||||||
// Need to evaluate again, typval_compare() overwrites "tv".
|
// Need to evaluate again, typval_compare() overwrites "tv".
|
||||||
typval_T *v = eval_expr(bp->dbg_name);
|
typval_T *const v = eval_expr_restore(bp);
|
||||||
debug_newval = typval_tostring(v);
|
debug_newval = typval_tostring(v);
|
||||||
tv_free(bp->dbg_val);
|
tv_free(bp->dbg_val);
|
||||||
bp->dbg_val = v;
|
bp->dbg_val = v;
|
||||||
@@ -806,8 +823,6 @@ debuggy_find(
|
|||||||
lnum = after > 0 ? after : 1;
|
lnum = after > 0 ? after : 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
got_int |= prev_got_int;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name != fname) {
|
if (name != fname) {
|
||||||
|
@@ -314,9 +314,12 @@ func Test_Debugger()
|
|||||||
call RunDbgCmd(buf, 'enew! | only!')
|
call RunDbgCmd(buf, 'enew! | only!')
|
||||||
|
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_Debugger_breakadd()
|
||||||
" Tests for :breakadd file and :breakadd here
|
" Tests for :breakadd file and :breakadd here
|
||||||
" Breakpoints should be set before sourcing the file
|
" Breakpoints should be set before sourcing the file
|
||||||
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
let var1 = 10
|
let var1 = 10
|
||||||
@@ -337,6 +340,10 @@ func Test_Debugger()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
|
|
||||||
call delete('Xtest.vim')
|
call delete('Xtest.vim')
|
||||||
|
%bw!
|
||||||
|
|
||||||
|
call assert_fails('breakadd here', 'E32:')
|
||||||
|
call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_Backtrace_Through_Source()
|
func Test_Backtrace_Through_Source()
|
||||||
|
Reference in New Issue
Block a user