{
struct breakpoint *b = bl->owner;
+ /* By definition, the inferior does not report stops at
+ tracepoints. */
+ if (b->type == bp_tracepoint)
+ return 0;
+
if (b->type != bp_watchpoint
&& b->type != bp_hardware_watchpoint
&& b->type != bp_read_watchpoint
if (expanded.nelts == 1)
{
- /* We had one sal, we got one sal. Without futher
- processing, just return the original sal. */
+ /* We had one sal, we got one sal. Return that sal, adjusting it
+ past the function prologue if necessary. */
xfree (expanded.sals);
expanded.nelts = 1;
expanded.sals = xmalloc (sizeof (struct symtab_and_line));
sal.pc = original_pc;
expanded.sals[0] = sal;
+ skip_prologue_sal (&expanded.sals[0]);
do_cleanups (old_chain);
return expanded;
}
if (tok == tmptok)
error (_("Junk after task keyword."));
if (!valid_task_id (*task))
- error (_("Unknown task %d\n"), *task);
+ error (_("Unknown task %d."), *task);
}
else
error (_("Junk at end of arguments."));
{
}
+/* Invalidate last known value of any hardware watchpoint if
+ the memory which that value represents has been written to by
+ GDB itself. */
+
+static void
+invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len,
+ const bfd_byte *data)
+{
+ struct breakpoint *bp;
+
+ ALL_BREAKPOINTS (bp)
+ if (bp->enable_state == bp_enabled
+ && bp->type == bp_hardware_watchpoint
+ && bp->val_valid && bp->val)
+ {
+ struct bp_location *loc;
+
+ for (loc = bp->loc; loc != NULL; loc = loc->next)
+ if (loc->loc_type == bp_loc_hardware_watchpoint
+ && loc->address + loc->length > addr
+ && addr + len > loc->address)
+ {
+ value_free (bp->val);
+ bp->val = NULL;
+ bp->val_valid = 0;
+ }
+ }
+}
+
/* Use default_breakpoint_'s, or nothing if they aren't valid. */
struct symtabs_and_lines
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
observer_attach_inferior_exit (clear_syscall_counts);
+ observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful