vim-patch:7.4.1102

Problem:    Debugger has no stack backtrace support.
Solution:   Add "backtrace", "frame", "up" and "down" commands. (Alberto
            Fanjul, closes vim/vim#433)

f1f60f859c
This commit is contained in:
Jurica Bradaric
2016-05-10 21:34:56 +02:00
parent 68717132b1
commit b4cbfd3c08
6 changed files with 372 additions and 13 deletions

View File

@@ -116,6 +116,11 @@ struct source_cookie {
static int debug_greedy = FALSE; /* batch mode debugging: don't save
and restore typeahead. */
static int get_maxbacktrace_level(void);
static void do_setdebugtracelevel(char_u *arg);
static void do_checkbacktracelevel(void);
static void do_showbacktrace(char_u *cmd);
/*
* do_debug(): Debug mode.
* Repeatedly get Ex commands, until told to continue normal execution.
@@ -144,6 +149,10 @@ void do_debug(char_u *cmd)
#define CMD_FINISH 4
#define CMD_QUIT 5
#define CMD_INTERRUPT 6
#define CMD_BACKTRACE 7
#define CMD_FRAME 8
#define CMD_UP 9
#define CMD_DOWN 10
++RedrawingDisabled; /* don't redisplay the window */
@@ -194,6 +203,7 @@ void do_debug(char_u *cmd)
ex_normal_busy = save_ex_normal_busy;
cmdline_row = msg_row;
msg_starthere();
if (cmdline != NULL) {
/* If this is a debug command, set "last_cmd".
* If not, reset "last_cmd".
@@ -210,8 +220,15 @@ void do_debug(char_u *cmd)
case 's': last_cmd = CMD_STEP;
tail = "tep";
break;
case 'f': last_cmd = CMD_FINISH;
tail = "inish";
case 'f':
last_cmd = 0;
if (p[1] == 'r') {
last_cmd = CMD_FRAME;
tail = "rame";
} else {
last_cmd = CMD_FINISH;
tail = "inish";
}
break;
case 'q': last_cmd = CMD_QUIT;
tail = "uit";
@@ -219,6 +236,26 @@ void do_debug(char_u *cmd)
case 'i': last_cmd = CMD_INTERRUPT;
tail = "nterrupt";
break;
case 'b':
last_cmd = CMD_BACKTRACE;
if (p[1] == 't') {
tail = "t";
} else {
tail = "acktrace";
}
break;
case 'w':
last_cmd = CMD_BACKTRACE;
tail = "here";
break;
case 'u':
last_cmd = CMD_UP;
tail = "p";
break;
case 'd':
last_cmd = CMD_DOWN;
tail = "own";
break;
default: last_cmd = 0;
}
if (last_cmd != 0) {
@@ -228,8 +265,9 @@ void do_debug(char_u *cmd)
++p;
++tail;
}
if (ASCII_ISALPHA(*p))
if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) {
last_cmd = 0;
}
}
}
@@ -259,7 +297,28 @@ void do_debug(char_u *cmd)
/* Do not repeat ">interrupt" cmd, continue stepping. */
last_cmd = CMD_STEP;
break;
case CMD_BACKTRACE:
do_showbacktrace(cmd);
continue;
case CMD_FRAME:
if (*p == NUL) {
do_showbacktrace(cmd);
} else {
p = skipwhite(p);
do_setdebugtracelevel(p);
}
continue;
case CMD_UP:
debug_backtrace_level++;
do_checkbacktracelevel();
continue;
case CMD_DOWN:
debug_backtrace_level--;
do_checkbacktracelevel();
continue;
}
// Going out reset backtrace_level
debug_backtrace_level = 0;
break;
}
@@ -294,6 +353,78 @@ void do_debug(char_u *cmd)
debug_did_msg = TRUE;
}
static int get_maxbacktrace_level(void)
{
int maxbacktrace = 0;
if (sourcing_name != NULL) {
char *p = (char *)sourcing_name;
char *q;
while ((q = strstr(p, "..")) != NULL) {
p = q + 2;
maxbacktrace++;
}
}
return maxbacktrace;
}
static void do_setdebugtracelevel(char_u *arg)
{
int level = atoi((char *)arg);
if (*arg == '+' || level < 0) {
debug_backtrace_level += level;
} else {
debug_backtrace_level = level;
}
do_checkbacktracelevel();
}
static void do_checkbacktracelevel(void)
{
if (debug_backtrace_level < 0) {
debug_backtrace_level = 0;
MSG(_("frame is zero"));
} else {
int max = get_maxbacktrace_level();
if (debug_backtrace_level > max) {
debug_backtrace_level = max;
smsg(_("frame at highest level: %d"), max);
}
}
}
static void do_showbacktrace(char_u *cmd)
{
if (sourcing_name != NULL) {
int i = 0;
int max = get_maxbacktrace_level();
char *cur = (char *)sourcing_name;
while (!got_int) {
char *next = strstr(cur, "..");
if (next != NULL) {
*next = NUL;
}
if (i == max - debug_backtrace_level) {
smsg("->%d %s", max - i, cur);
} else {
smsg(" %d %s", max - i, cur);
}
i++;
if (next == NULL) {
break;
}
*next = '.';
cur = next + 2;
}
}
if (sourcing_lnum != 0) {
smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
} else {
smsg(_("cmd: %s"), cmd);
}
}
/*
* ":debug".
*/