diff options
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index a3a7c17..7e020c5 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -834,30 +834,30 @@ void set_breakpoint_condition (struct breakpoint *b, const char *exp, int from_tty) { - if (is_watchpoint (b)) - { - struct watchpoint *w = (struct watchpoint *) b; - - w->cond_exp.reset (); - } - else + if (*exp == 0) { - struct bp_location *loc; + xfree (b->cond_string); + b->cond_string = nullptr; - for (loc = b->loc; loc; loc = loc->next) + if (is_watchpoint (b)) { - loc->cond.reset (); + struct watchpoint *w = (struct watchpoint *) b; - /* No need to free the condition agent expression - bytecode (if we have one). We will handle this - when we go through update_global_location_list. */ + w->cond_exp.reset (); } - } + else + { + struct bp_location *loc; - if (*exp == 0) - { - xfree (b->cond_string); - b->cond_string = nullptr; + for (loc = b->loc; loc; loc = loc->next) + { + loc->cond.reset (); + + /* No need to free the condition agent expression + bytecode (if we have one). We will handle this + when we go through update_global_location_list. */ + } + } if (from_tty) printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number); @@ -872,23 +872,40 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp, innermost_block_tracker tracker; arg = exp; - w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker); + expression_up new_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker); if (*arg) error (_("Junk at end of expression")); + w->cond_exp = std::move (new_exp); w->cond_exp_valid_block = tracker.block (); } else { struct bp_location *loc; + /* Parse and set condition expressions. We make two passes. + In the first, we parse the condition string to see if it + is valid in all locations. If so, the condition would be + accepted. So we go ahead and set the locations' + conditions. In case a failing case is found, we throw + the error and the condition string will be rejected. + This two-pass approach is taken to avoid setting the + state of locations in case of a reject. */ + for (loc = b->loc; loc; loc = loc->next) + { + arg = exp; + parse_exp_1 (&arg, loc->address, + block_for_pc (loc->address), 0); + if (*arg != 0) + error (_("Junk at end of expression")); + } + + /* If we reach here, the condition is valid at all locations. */ for (loc = b->loc; loc; loc = loc->next) { arg = exp; loc->cond = parse_exp_1 (&arg, loc->address, block_for_pc (loc->address), 0); - if (*arg) - error (_("Junk at end of expression")); } } |