#include "cli/cli-script.h"
#include "gdb_assert.h"
#include "block.h"
+#include "solist.h"
+#include "observer.h"
#include "gdb-events.h"
shadow contents, not the breakpoints themselves. From breakpoint.c. */
int
-read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
+deprecated_read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
{
int status;
struct bp_location *b;
if (bp_addr > memaddr)
{
/* Copy the section of memory before the breakpoint. */
- status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+ status = deprecated_read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
if (status != 0)
return status;
}
if (bp_addr + bp_size < memaddr + len)
{
/* Copy the section of memory after the breakpoint. */
- status = read_memory_nobpt (bp_addr + bp_size,
+ status = deprecated_read_memory_nobpt (bp_addr + bp_size,
myaddr + bp_addr + bp_size - memaddr,
memaddr + len - (bp_addr + bp_size));
if (status != 0)
return 0;
}
-/* Return nonzero if FRAME is a dummy frame. We can't use
- DEPRECATED_PC_IN_CALL_DUMMY because figuring out the saved SP would
- take too much time, at least using frame_register() on the 68k.
- This means that for this function to work right a port must use the
- bp_call_dummy breakpoint. */
-
-int
-deprecated_frame_in_dummy (struct frame_info *frame)
-{
- struct breakpoint *b;
-
- /* This function is used by two files: get_frame_type(), after first
- checking that !DEPRECATED_USE_GENERIC_DUMMY_FRAMES; and
- sparc-tdep.c, which doesn't yet use generic dummy frames anyway. */
- gdb_assert (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES);
-
- ALL_BREAKPOINTS (b)
- {
- if (b->type == bp_call_dummy
- && frame_id_eq (b->frame_id, get_frame_id (frame))
- /* We need to check the PC as well as the frame on the sparc,
- for signals.exp in the testsuite. */
- && (get_frame_pc (frame)
- >= (b->loc->address
- - DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * DEPRECATED_REGISTER_SIZE))
- && get_frame_pc (frame) <= b->loc->address)
- return 1;
- }
- return 0;
-}
-
/* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
PC is valid for process/thread PTID. */
}
/* Get a bpstat associated with having just stopped at address
- BP_ADDR. */
+ BP_ADDR in thread PTID. STOPPED_BY_WATCHPOINT is 1 if the
+ target thinks we stopped due to a hardware watchpoint, 0 if we
+ know we did not trigger a hardware watchpoint, and -1 if we do not know. */
/* Determine whether we stopped at a breakpoint, etc, or whether we
don't understand this stop. Result is a chain of bpstat's such that:
commands, FIXME??? fields. */
bpstat
-bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
+bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid, int stopped_by_watchpoint)
{
struct breakpoint *b, *temp;
/* True if we've hit a breakpoint (as opposed to a watchpoint). */
if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
continue;
- /* Hardware watchpoints are treated as non-existent if the reason we
- stopped wasn't a hardware watchpoint (we didn't stop on some data
- address). Otherwise gdb won't stop on a break instruction in the code
- (not from a breakpoint) when a hardware watchpoint has been defined. */
if (b->type != bp_watchpoint
- && !((b->type == bp_hardware_watchpoint
- || b->type == bp_read_watchpoint
- || b->type == bp_access_watchpoint)
- && target_stopped_data_address () != 0)
+ && b->type != bp_hardware_watchpoint
+ && b->type != bp_read_watchpoint
+ && b->type != bp_access_watchpoint
&& b->type != bp_hardware_breakpoint
&& b->type != bp_catch_fork
&& b->type != bp_catch_vfork
continue;
}
+ /* Continuable hardware watchpoints are treated as non-existent if the
+ reason we stopped wasn't a hardware watchpoint (we didn't stop on
+ some data address). Otherwise gdb won't stop on a break instruction
+ in the code (not from a breakpoint) when a hardware watchpoint has
+ been defined. */
+
+ if ((b->type == bp_hardware_watchpoint
+ || b->type == bp_read_watchpoint
+ || b->type == bp_access_watchpoint)
+ && !stopped_by_watchpoint)
+ continue;
+
if (b->type == bp_hardware_breakpoint)
{
if (b->loc->address != bp_addr)
char astr1[40];
char astr2[40];
- strcpy (astr1, local_hex_string_custom ((unsigned long) from_addr, "08l"));
- strcpy (astr2, local_hex_string_custom ((unsigned long) to_addr, "08l"));
+ strcpy (astr1, hex_string_custom ((unsigned long) from_addr, 8));
+ strcpy (astr2, hex_string_custom ((unsigned long) to_addr, 8));
if (have_bnum)
warning ("Breakpoint %d address previously adjusted from %s to %s.",
bnum, astr1, astr2);
b->enable_state = bp_enabled;
/* addr_string has to be used or breakpoint_re_set will delete me. */
- xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
+ b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
return b;
}
}
}
+/* Disable any breakpoints that are in in an unloaded shared library. Only
+ apply to enabled breakpoints, disabled ones can just stay disabled. */
+
+void
+disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
+{
+ struct breakpoint *b;
+ int disabled_shlib_breaks = 0;
+
+#if defined (PC_SOLIB)
+ /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
+ ALL_BREAKPOINTS (b)
+ {
+ if ((b->loc->loc_type == bp_loc_hardware_breakpoint
+ || b->loc->loc_type == bp_loc_software_breakpoint)
+ && breakpoint_enabled (b)
+ && !b->loc->duplicate)
+ {
+ char *so_name = PC_SOLIB (b->loc->address);
+ if (so_name
+ && !strcmp (so_name, solib->so_name))
+ {
+ b->enable_state = bp_shlib_disabled;
+ /* At this point, we cannot rely on remove_breakpoint
+ succeeding so we must mark the breakpoint as not inserted
+ to prevent future errors occurring in remove_breakpoints. */
+ b->loc->inserted = 0;
+ if (!disabled_shlib_breaks)
+ {
+ target_terminal_ours_for_output ();
+ warning ("Temporarily disabling breakpoints for unloaded shared library \"%s\"",
+ so_name);
+ }
+ disabled_shlib_breaks = 1;
+ }
+ }
+ }
+#endif
+}
+
/* Try to reenable any breakpoints in shared libraries. */
void
re_enable_breakpoints_in_shlibs (void)
else
/* addr_string has to be used or breakpoint_re_set will delete
me. */
- xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
+ b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
b->cond_string = cond_string[i];
b->ignore_count = ignore_count;
b->enable_state = bp_enabled;
be copied too. */
if (pending_bp->commands)
b->commands = copy_command_lines (pending_bp->commands);
+
+ /* We have to copy over the ignore_count and thread as well. */
+ b->ignore_count = pending_bp->ignore_count;
+ b->thread = pending_bp->thread;
}
mention (b);
}
Give the target a chance to bless sals.sals[i].pc before we
try to make a breakpoint for it. */
- if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
+#ifdef DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE
+ if (DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
{
if (address == NULL)
error ("Cannot break without a running program.");
error ("Cannot break on %s without a running program.",
address);
}
+#endif
}
}
struct breakpoint *b = (struct breakpoint *) bint;
struct value *mark;
int i;
+ int not_found;
+ int *not_found_ptr = NULL;
struct symtabs_and_lines sals;
char *s;
enum enable_state save_enable;
save_enable = b->enable_state;
if (b->enable_state != bp_shlib_disabled)
b->enable_state = bp_disabled;
+ else
+ /* If resetting a shlib-disabled breakpoint, we don't want to
+ see an error message if it is not found since we will expect
+ this to occur until the shared library is finally reloaded.
+ We accomplish this by giving decode_line_1 a pointer to use
+ for silent notification that the symbol is not found. */
+ not_found_ptr = ¬_found;
set_language (b->language);
input_radix = b->input_radix;
s = b->addr_string;
- sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL);
+ sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
+ not_found_ptr);
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
static struct cmd_list_element *breakpoint_show_cmdlist;
struct cmd_list_element *c;
+#ifdef SOLIB_ADD
+ observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+#endif
+
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
before a breakpoint is set. */
created before setting this to nonzero, will continue to use watchpoint\n\
hardware.)",
&setlist);
- add_show_from_set (c, &showlist);
+ deprecated_add_show_from_set (c, &showlist);
can_use_hw_watchpoints = 1;
0/*allow-unknown*/, &showlist);
add_setshow_auto_boolean_cmd ("pending", no_class, &pending_break_support, "\
-Set debugger's behavior regarding pending breakpoints.\n\
-If on, an unrecognized breakpoint location will cause gdb to create a\n\
-pending breakpoint. If off, an unrecognized breakpoint location results in\n\
-an error. If auto, an unrecognized breakpoint location results in a\n\
-user-query to see if a pending breakpoint should be created.","\
-Show debugger's behavior regarding pending breakpoints.\n\
+Set debugger's behavior regarding pending breakpoints.", "\
+Show debugger's behavior regarding pending breakpoints.", "\
If on, an unrecognized breakpoint location will cause gdb to create a\n\
pending breakpoint. If off, an unrecognized breakpoint location results in\n\
an error. If auto, an unrecognized breakpoint location results in a\n\
-user-query to see if a pending breakpoint should be created.",
+user-query to see if a pending breakpoint should be created.", "\
+Debugger's behavior regarding pending breakpoints is %s.",
NULL, NULL,
&breakpoint_set_cmdlist,
&breakpoint_show_cmdlist);