Skip to content

Commit

Permalink
WIP: Trepan-Debuggers#107: Debugger "watchpoints": break when the com…
Browse files Browse the repository at this point in the history
…mand executed matches a certain regex.
  • Loading branch information
Viktor Sergiienko committed May 11, 2020
1 parent e71c61b commit 796366c
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 17 deletions.
3 changes: 3 additions & 0 deletions debug-test/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

# Run as ./make -f debug-test/Makefile -X --debugger-stop=preaction,
# then do `watch Hell.`.

UNEXPANDED=expanded

all: test
Expand Down
27 changes: 14 additions & 13 deletions libdebugger/break.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */
enum breakpoint_type
{
LINE,
COMMAND
COMMAND_WATCH
};

/*! Node for an item in the target call stack */
Expand Down Expand Up @@ -138,8 +138,8 @@ remove_breakpoint (unsigned int i, bool silent)

if (p_prev) p_prev->p_next = p->p_next;

if (p->type == COMMAND) {
dbg_msg(_("Command watchpoint %u cleared."), i); // on regex `%s' TODO: Save the original regex?
if (p->type == COMMAND_WATCH) {
dbg_msg(_("Command watchpoint %u cleared."), i);
regfree(&p->regex);
free(p->psz_text);
free(p);
Expand Down Expand Up @@ -201,16 +201,19 @@ add_command_breakpoint(const char *psz_regex)

if (!p_new) return false;

re_compile_status = regcomp(&p_new->regex, "psz_regex", REG_EXTENDED | REG_NOSUB);
re_compile_status = regcomp(&p_new->regex, psz_regex, REG_EXTENDED | REG_NOSUB);

// Not sure if regex_t can be memmoved, so initializing it in allocated breakpoint_node_t.
// Not sure if regex_t can be memmoved, so initializing it in the allocated breakpoint_node_t.
if (re_compile_status != 0) {
dbg_msg("Could not compile regex: %s", psz_regex);
char reg_error_message[100];
regerror(re_compile_status, &p_new->regex, reg_error_message, sizeof(reg_error_message)-1);
dbg_msg("Could not compile regex: %s: %s", psz_regex, reg_error_message);
regfree(&p_new->regex);
free(p_new);
return false;
}

p_new->type = COMMAND;
p_new->type = COMMAND_WATCH;
p_new->psz_text = strdup(psz_regex);
p_new->i_num = ++i_breakpoints;
p_new->p_target = NULL;
Expand All @@ -234,10 +237,9 @@ any_command_breakpoint_matches(const char *psz_expanded_command)
breakpoint_node_t *p;

for (p = p_breakpoint_top; p; p = p->p_next) {
if (p->type == COMMAND) {
int matches = regexec(&p->regex, psz_expanded_command, (size_t) 0, NULL, 0);
printf("DEBUG: Checking if command %s matches %s: %s\n", psz_expanded_command, p->psz_text, matches ? "yes" : "no");
if (matches == 0) {
if (p->type == COMMAND_WATCH) {
int match_status = regexec(&p->regex, psz_expanded_command, (size_t) 0, NULL, 0);
if (match_status == 0) {
return true;
}
}
Expand All @@ -250,8 +252,7 @@ void
check_command_breakpoint(target_stack_node_t *p_call_stack, const char *psz_expanded_command)
{
if (any_command_breakpoint_matches (psz_expanded_command)) {
// TODO: Probably we need a new reason, other than DEBUG_BRKPT_AFTER_PREREQ.
enter_debugger (p_call_stack, p_call_stack->p_target, 0, DEBUG_BRKPT_AFTER_PREREQ);
enter_debugger (p_call_stack, p_call_stack->p_target, 0, DEBUG_WATCHPOINT);
}
}

Expand Down
5 changes: 4 additions & 1 deletion libdebugger/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ debug_return_t enter_debugger (target_stack_node_t *p,
if (!p_target->tracing) return continue_execution;
} else if ( !debugger_on_error
&& !(i_debugger_stepping || i_debugger_nexting)
&& p_target && !p_target->tracing && -2 != errcode )
&& p_target && !p_target->tracing && -2 != errcode
&& reason != DEBUG_WATCHPOINT) {
return continue_execution;
}

/* Clear temporary breakpoints. */
if (p_target && p_target->tracing & BRK_TEMP)
Expand All @@ -274,6 +276,7 @@ debug_return_t enter_debugger (target_stack_node_t *p,
case DEBUG_BRKPT_AFTER_CMD:
case DEBUG_BRKPT_BEFORE_PREREQ:
case DEBUG_BRKPT_AFTER_PREREQ:
case DEBUG_WATCHPOINT: // FIXME: I have about no idea what I'm doing here. Should this reason be "cleared"?
p_target->tracing = BRK_NONE;
default:
;
Expand Down
4 changes: 2 additions & 2 deletions libdebugger/command/watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ dbg_cmd_watch (char *psz_regex)

added = add_command_breakpoint(psz_regex);
if (added) {
printf("Added command watchpoint %s\n", psz_regex);
printf("Added command watchpoint: '%s'\n", psz_regex);
} else {
printf("Error adding command watchpoint %s\n", psz_regex);
printf("Error adding command watchpoint: '%s'\n", psz_regex);
}

return debug_readloop;
Expand Down
3 changes: 2 additions & 1 deletion libdebugger/fns.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ static const char *reason2str[] = {
"!!",
"--",
"++",
":o"
":o",
"re"
};


Expand Down
1 change: 1 addition & 0 deletions src/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef enum
DEBUG_STEP_HIT = 6,
DEBUG_STEP_COMMAND = 7,
DEBUG_EXPLICIT_CALL = 8,
DEBUG_WATCHPOINT = 9,
DEBUG_STACK_CHANGING = 99,
DEBUG_NOT_GIVEN = 100
} debug_enter_reason_t;
Expand Down

1 comment on commit 796366c

@rocky
Copy link

@rocky rocky commented on 796366c May 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great so far.

So far I have only looked over the diffs here. I'll look at the code in more detail though when I get a chance.

I especially appreciate the fact that you are following existing gdb nominclature and concepts in adding a new feature rather than calling it something different which would make it harder for me and others to discover or remember

Please sign in to comment.