/* Everything about breakpoints, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
- Foundation, Inc.
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GDB.
B ? (TMP=B->next, 1): 0; \
B = TMP)
-/* True if SHIFT_INST_REGS defined, false otherwise. */
-
-int must_shift_inst_regs =
-#if defined(SHIFT_INST_REGS)
-1
-#else
-0
-#endif
- ;
-
/* True if breakpoint hit counts should be displayed in breakpoint info. */
int show_breakpoint_hit_counts = 1;
error ("catch of library unloads not yet implemented on this platform")
#endif
+/* Return whether a breakpoint is an active enabled breakpoint. */
+static int
+breakpoint_enabled (struct breakpoint *b)
+{
+ return b->enable_state == bp_enabled;
+}
+
/* Set breakpoint count to NUM. */
void
/* Permanent breakpoints cannot be inserted or removed. Disabled
breakpoints should not be inserted. */
- if (bpt->owner->enable_state != bp_enabled)
+ if (!breakpoint_enabled (bpt->owner))
return 0;
if (bpt->inserted || bpt->duplicate)
bpt->owner->enable_state = bp_disabled;
else
bpt->inserted = 1;
- return val;
+
+ /* We've already printed an error message if there was a problem
+ inserting this catchpoint, and we've disabled the catchpoint,
+ so just return success. */
+ return 0;
}
return 0;
{
/* Permanent breakpoints cannot be inserted or removed. Disabled
breakpoints should not be inserted. */
- if (b->owner->enable_state != bp_enabled)
+ if (!breakpoint_enabled (b->owner))
continue;
/* FIXME drow/2003-10-07: This code should be pushed elsewhere when
b->inserted = (is == mark_inserted);
}
else if (b->loc_type == bp_loc_hardware_watchpoint
- && b->owner->enable_state == bp_enabled
+ && breakpoint_enabled (b->owner)
&& !b->duplicate)
{
struct value *v;
else if ((b->owner->type == bp_catch_fork ||
b->owner->type == bp_catch_vfork ||
b->owner->type == bp_catch_exec)
- && b->owner->enable_state == bp_enabled
+ && breakpoint_enabled (b->owner)
&& !b->duplicate)
{
val = -1;
}
else if ((b->owner->type == bp_catch_catch ||
b->owner->type == bp_catch_throw)
- && b->owner->enable_state == bp_enabled
+ && breakpoint_enabled (b->owner)
&& !b->duplicate)
{
}
else if (ep_is_exception_catchpoint (b->owner)
&& b->inserted /* sometimes previous insert doesn't happen */
- && b->owner->enable_state == bp_enabled
+ && breakpoint_enabled (b->owner)
&& !b->duplicate)
{
&& bpt->loc_type != bp_loc_hardware_breakpoint)
continue;
- if ((bpt->owner->enable_state == bp_enabled
+ if ((breakpoint_enabled (bpt->owner)
|| bpt->owner->enable_state == bp_permanent)
&& bpt->address == pc) /* bp is enabled and matches pc */
{
&& bpt->loc_type != bp_loc_hardware_breakpoint)
continue;
- if ((bpt->owner->enable_state == bp_enabled
+ if ((breakpoint_enabled (bpt->owner)
|| bpt->owner->enable_state == bp_permanent)
&& bpt->address == pc
&& (bpt->owner->thread == -1 || bpt->owner->thread == thread))
{
bpstat bs;
struct cleanup *old_chain;
- struct command_line *cmd;
/* Avoid endless recursion if a `source' command is contained
in bs->commands. */
breakpoint_proceeded = 0;
for (; bs != NULL; bs = bs->next)
{
+ struct command_line *cmd;
+ struct cleanup *this_cmd_tree_chain;
+
+ /* Take ownership of the BSP's command tree, if it has one.
+
+ The command tree could legitimately contain commands like
+ 'step' and 'next', which call clear_proceed_status, which
+ frees stop_bpstat's command tree. To make sure this doesn't
+ free the tree we're executing out from under us, we need to
+ take ownership of the tree ourselves. Since a given bpstat's
+ commands are only executed once, we don't need to copy it; we
+ can clear the pointer in the bpstat, and make sure we free
+ the tree when we're done. */
cmd = bs->commands;
+ bs->commands = 0;
+ this_cmd_tree_chain = make_cleanup_free_command_lines (&cmd);
+
while (cmd != NULL)
{
execute_control_command (cmd);
else
cmd = cmd->next;
}
+
+ /* We can free this command tree now. */
+ do_cleanups (this_cmd_tree_chain);
+
if (breakpoint_proceeded)
/* The inferior is proceeded by the command; bomb out now.
The bpstat chain has been blown away by wait_for_inferior.
But since execution has stopped again, there is a new bpstat
to look at, so start over. */
goto top;
- else
- free_command_lines (&bs->commands);
}
do_cleanups (old_chain);
}
ALL_BREAKPOINTS_SAFE (b, temp)
{
- if (b->enable_state == bp_disabled
- || b->enable_state == bp_shlib_disabled
- || b->enable_state == bp_call_disabled)
+ if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
continue;
if (b->type != bp_watchpoint
if (b->type == bp_hardware_breakpoint)
{
- if (b->loc->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+ if (b->loc->address != *pc)
continue;
if (overlay_debugging /* unmapped overlay section */
&& section_is_overlay (b->loc->section)
bs->print = 0;
bs->commands = b->commands;
if (bs->commands &&
- (STREQ ("silent", bs->commands->line) ||
- (xdb_commands && STREQ ("Q", bs->commands->line))))
+ (strcmp ("silent", bs->commands->line) == 0
+ || (xdb_commands && strcmp ("Q", bs->commands->line) == 0)))
{
bs->commands = bs->commands->next;
bs->print = 0;
if (real_breakpoint && bs)
{
- if (bs->breakpoint_at->type == bp_hardware_breakpoint)
- {
- if (DECR_PC_AFTER_HW_BREAK != 0)
- {
- *pc = *pc - DECR_PC_AFTER_HW_BREAK;
- write_pc (*pc);
- }
- }
- else
+ if (bs->breakpoint_at->type != bp_hardware_breakpoint)
{
- if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
+ if (DECR_PC_AFTER_BREAK != 0)
{
*pc = bp_addr;
-#if defined (SHIFT_INST_REGS)
- SHIFT_INST_REGS ();
-#else /* No SHIFT_INST_REGS. */
write_pc (bp_addr);
-#endif /* No SHIFT_INST_REGS. */
}
}
}
{
struct breakpoint *b;
ALL_BREAKPOINTS (b)
- if (b->enable_state == bp_enabled && b->type == bp_watchpoint)
+ if (breakpoint_enabled (b) && b->type == bp_watchpoint)
return 1;
return 0;
}
{
struct bp_location *bpt;
ALL_BP_LOCATIONS (bpt)
- if ((bpt->owner->enable_state == bp_enabled)
+ if (breakpoint_enabled (bpt->owner)
&& bpt->inserted
&& bpt->loc_type == bp_loc_hardware_watchpoint)
return 1;
#if defined (PC_SOLIB)
if (((b->type == bp_breakpoint) ||
(b->type == bp_hardware_breakpoint)) &&
- b->enable_state == bp_enabled &&
+ breakpoint_enabled (b) &&
!b->loc->duplicate &&
PC_SOLIB (b->loc->address))
{
ALL_BREAKPOINTS (b)
if (b->enable_state == bp_shlib_disabled)
{
- char buf[1];
+ char buf[1], *lib;
/* Do not reenable the breakpoint if the shared library
is still not mapped in. */
- if (target_read_memory (b->loc->address, buf, 1) == 0)
+ lib = PC_SOLIB (b->loc->address);
+ if (lib != NULL && target_read_memory (b->loc->address, buf, 1) == 0)
b->enable_state = bp_enabled;
}
}
int thread = -1; /* All threads. */
/* Set a breakpoint on the specified hook. */
- sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical);
+ sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical, NULL);
addr_end = hookname;
if (sals.nelts == 0)
*other_type_used = 0;
ALL_BREAKPOINTS (b)
{
- if (b->enable_state == bp_enabled)
+ if (breakpoint_enabled (b))
{
if (b->type == type)
i++;
else if ((b->type == bp_hardware_watchpoint ||
b->type == bp_read_watchpoint ||
- b->type == bp_access_watchpoint)
- && b->enable_state == bp_enabled)
+ b->type == bp_access_watchpoint))
*other_type_used = 1;
}
}
|| (b->type == bp_read_watchpoint)
|| (b->type == bp_access_watchpoint)
|| ep_is_exception_catchpoint (b))
- && (b->enable_state == bp_enabled))
+ && breakpoint_enabled (b))
{
b->enable_state = bp_call_disabled;
check_duplicates (b);
|| ((strchr ("+-", (*address)[0]) != NULL)
&& ((*address)[1] != '['))))
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
- default_breakpoint_line, addr_string);
+ default_breakpoint_line, addr_string, NULL);
else
- *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
+ *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string, NULL);
}
/* For any SAL that didn't have a canonical string, fill one in. */
if (sals->nelts > 0 && *addr_string == NULL)
beg_addr_string = addr_string;
sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0,
- (char ***) NULL);
+ (char ***) NULL, NULL);
xfree (beg_addr_string);
old_chain = make_cleanup (xfree, sals.sals);
if (default_breakpoint_valid)
sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
- default_breakpoint_line, (char ***) NULL);
+ default_breakpoint_line, (char ***) NULL, NULL);
else
sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
- 0, (char ***) NULL);
+ 0, (char ***) NULL, NULL);
if (sals.nelts != 1)
error ("Couldn't get information on specified line.");
trigger_func_name = xstrdup ("__cxa_throw");
nameptr = trigger_func_name;
- sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL);
+ sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL, NULL);
if (sals.nelts == 0)
{
xfree (trigger_func_name);
|| ((default_match || (0 == sal.pc))
&& b->source_file != NULL
&& sal.symtab != NULL
- && STREQ (b->source_file, sal.symtab->filename)
+ && strcmp (b->source_file, sal.symtab->filename) == 0
&& b->line_number == sal.line)))
/* Yes, if sal source file and line matches b. */
{
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);
+ sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL);
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
the source file name or the line number changes... */
|| (b->source_file != NULL
&& sals.sals[i].symtab != NULL
- && (!STREQ (b->source_file, sals.sals[i].symtab->filename)
+ && (strcmp (b->source_file, sals.sals[i].symtab->filename) != 0
|| b->line_number != sals.sals[i].line)
)
/* ...or we switch between having a source file and not having
value_free (b->val);
b->val = evaluate_expression (b->exp);
release_value (b->val);
- if (VALUE_LAZY (b->val) && b->enable_state == bp_enabled)
+ if (VALUE_LAZY (b->val) && breakpoint_enabled (b))
value_fetch_lazy (b->val);
if (b->cond_string != NULL)
xfree (b->cond);
b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
}
- if (b->enable_state == bp_enabled)
+ if (breakpoint_enabled (b))
mention (b);
value_free_to_mark (mark);
break;
sals = decode_line_1 (&string, funfirstline,
default_breakpoint_symtab,
default_breakpoint_line,
- (char ***) NULL);
+ (char ***) NULL, NULL);
else
sals = decode_line_1 (&string, funfirstline,
- (struct symtab *) NULL, 0, (char ***) NULL);
+ (struct symtab *) NULL, 0, (char ***) NULL, NULL);
if (*string)
error ("Junk at end of line specification: %s", string);
return sals;