static int can_use_hardware_watchpoint (struct value *);
-static int break_command_1 (char *, int, int, struct breakpoint *);
+static int break_command_1 (char *, int, int);
static void mention (struct breakpoint *);
static void breakpoint_1 (int, int);
-static bpstat bpstat_alloc (struct bp_location *, bpstat);
+static bpstat bpstat_alloc (const struct bp_location *, bpstat);
static int breakpoint_cond_eval (void *);
static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
-static void solib_load_unload_1 (char *hookname,
- int tempflag,
- char *dll_pathname,
- char *cond_string, enum bptype bp_kind);
-
static void create_fork_vfork_event_catchpoint (int tempflag,
char *cond_string,
enum bptype bp_kind);
static void free_bp_location (struct bp_location *loc);
+static void mark_breakpoints_out (void);
+
/* Prototypes for exported functions. */
/* If FALSE, gdb will not use hardware support for watchpoints, even
read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len)
{
int status;
- struct bp_location *b;
+ const struct bp_location *b;
CORE_ADDR bp_addr = 0;
int bp_size = 0;
{
int val = 0;
- /* Permanent breakpoints cannot be inserted or removed. Disabled
- breakpoints should not be inserted. */
if (!breakpoint_enabled (bpt->owner))
return 0;
ALL_BP_LOCATIONS_SAFE (b, temp)
{
- /* Permanent breakpoints cannot be inserted or removed. Disabled
- breakpoints should not be inserted. */
if (!breakpoint_enabled (b->owner))
continue;
/* Clear the "inserted" flag in all breakpoints. */
-void
+static void
mark_breakpoints_out (void)
{
struct bp_location *bpt;
enum breakpoint_here
breakpoint_here_p (CORE_ADDR pc)
{
- struct bp_location *bpt;
+ const struct bp_location *bpt;
int any_breakpoint_here = 0;
ALL_BP_LOCATIONS (bpt)
int
breakpoint_inserted_here_p (CORE_ADDR pc)
{
- struct bp_location *bpt;
+ const struct bp_location *bpt;
ALL_BP_LOCATIONS (bpt)
{
int
software_breakpoint_inserted_here_p (CORE_ADDR pc)
{
- struct bp_location *bpt;
+ const struct bp_location *bpt;
int any_breakpoint_here = 0;
ALL_BP_LOCATIONS (bpt)
int
breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
{
- struct bp_location *bpt;
+ const struct bp_location *bpt;
int thread;
thread = pid_to_thread_id (ptid);
{
struct cleanup *old_chain, *ui_out_chain;
struct breakpoint *b;
- struct bp_location *bl;
+ const struct bp_location *bl;
struct ui_stream *stb;
stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (stb);
case print_it_normal:
{
- struct bp_location *bl = bs->breakpoint_at;
+ const struct bp_location *bl = bs->breakpoint_at;
struct breakpoint *b = bl ? bl->owner : NULL;
/* Normal case. Call the breakpoint's print_it method, or
/* Allocate a new bpstat and chain it to the current one. */
static bpstat
-bpstat_alloc (struct bp_location *bl, bpstat cbs /* Current "bs" value */ )
+bpstat_alloc (const struct bp_location *bl, bpstat cbs /* Current "bs" value */ )
{
bpstat bs;
bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
{
struct breakpoint *b = NULL;
- struct bp_location *bl;
+ const struct bp_location *bl;
/* True if we've hit a breakpoint (as opposed to a watchpoint). */
int real_breakpoint = 0;
/* Root of the chain of bpstat's */
int
bpstat_have_active_hw_watchpoints (void)
{
- struct bp_location *bpt;
+ const struct bp_location *bpt;
ALL_BP_LOCATIONS (bpt)
if (breakpoint_enabled (bpt->owner)
&& bpt->inserted
/* Helper to set_raw_breakpoint below. Creates a breakpoint
that has type BPTYPE and has no locations as yet. */
-struct breakpoint *
+static struct breakpoint *
set_raw_breakpoint_without_location (enum bptype bptype)
{
struct breakpoint *b, *b1;
/* Disable any breakpoints that are in in an unloaded shared library. Only
apply to enabled breakpoints, disabled ones can just stay disabled. */
-void
+static void
disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
{
struct bp_location *loc;
}
}
-static void
-solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
- char *cond_string, enum bptype bp_kind)
-{
- struct breakpoint *b;
- struct symtabs_and_lines sals;
- struct cleanup *old_chain;
- struct cleanup *canonical_strings_chain = NULL;
- char *addr_start = hookname;
- char *addr_end = NULL;
- char **canonical = (char **) NULL;
- int thread = -1; /* All threads. */
-
- /* Set a breakpoint on the specified hook. */
- sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL,
- 0, &canonical, NULL);
- addr_end = hookname;
-
- if (sals.nelts == 0)
- {
- warning (_("Unable to set a breakpoint on dynamic linker callback.\n"
- "Suggest linking with /opt/langtools/lib/end.o.\n"
- "GDB will be unable to track shl_load/shl_unload calls."));
- return;
- }
- if (sals.nelts != 1)
- {
- warning (_("Unable to set unique breakpoint on dynamic linker callback.\n"
- "GDB will be unable to track shl_load/shl_unload calls."));
- return;
- }
-
- /* Make sure that all storage allocated in decode_line_1 gets freed
- in case the following errors out. */
- old_chain = make_cleanup (xfree, sals.sals);
- if (canonical != (char **) NULL)
- {
- make_cleanup (xfree, canonical);
- canonical_strings_chain = make_cleanup (null_cleanup, 0);
- if (canonical[0] != NULL)
- make_cleanup (xfree, canonical[0]);
- }
-
- resolve_sal_pc (&sals.sals[0]);
-
- /* Remove the canonical strings from the cleanup, they are needed below. */
- if (canonical != (char **) NULL)
- discard_cleanups (canonical_strings_chain);
-
- b = set_raw_breakpoint (sals.sals[0], bp_kind);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->cond_string = (cond_string == NULL) ?
- NULL : savestring (cond_string, strlen (cond_string));
- b->thread = thread;
-
- if (canonical != (char **) NULL && canonical[0] != NULL)
- b->addr_string = canonical[0];
- else if (addr_start)
- b->addr_string = savestring (addr_start, addr_end - addr_start);
-
- b->enable_state = bp_enabled;
- b->disposition = tempflag ? disp_del : disp_donttouch;
-
- if (dll_pathname == NULL)
- b->dll_pathname = NULL;
- else
- {
- b->dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
- strcpy (b->dll_pathname, dll_pathname);
- }
-
- mention (b);
- do_cleanups (old_chain);
-}
-
-void
-create_solib_load_event_breakpoint (char *hookname, int tempflag,
- char *dll_pathname, char *cond_string)
-{
- solib_load_unload_1 (hookname, tempflag, dll_pathname,
- cond_string, bp_catch_load);
-}
-
-void
-create_solib_unload_event_breakpoint (char *hookname, int tempflag,
- char *dll_pathname, char *cond_string)
-{
- solib_load_unload_1 (hookname, tempflag, dll_pathname,
- cond_string, bp_catch_unload);
-}
-
static void
create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
enum bptype bp_kind)
mention (b);
}
-void
+static void
create_fork_event_catchpoint (int tempflag, char *cond_string)
{
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
}
-void
+static void
create_vfork_event_catchpoint (int tempflag, char *cond_string)
{
create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
}
-void
+static void
create_exec_event_catchpoint (int tempflag, char *cond_string)
{
struct symtab_and_line sal;
/* Create a breakpoint with SAL as location. Use ADDR_STRING
as textual description of the location, and COND_STRING
- as condition expression.
-
- The paramter PENDING_BP is same as for the
- create_breakpoints function. */
+ as condition expression. */
static void
create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
char *cond_string,
enum bptype type, enum bpdisp disposition,
- int thread, int ignore_count, int from_tty,
- struct breakpoint *pending_bp)
+ int thread, int ignore_count, int from_tty)
{
struct breakpoint *b = NULL;
int i;
char *arg = b->cond_string;
loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0);
if (*arg)
- {
- if (pending_bp)
- error (_("Junk at end of pending breakpoint condition expression"));
- else
- error (_("Garbage %s follows condition"), arg);
- }
+ error (_("Garbage %s follows condition"), arg);
}
}
separate conditions for different overloaded functions, so
we take just a single condition string.
- The parameter PENDING_BP points to a pending breakpoint that is
- the basis of the breakpoints currently being created. The pending
- breakpoint may contain a separate condition string or commands
- that were added after the initial pending breakpoint was created.
-
NOTE: If the function succeeds, the caller is expected to cleanup
the arrays ADDR_STRING, COND_STRING, and SALS (but not the
array contents). If the function fails (error() is called), the
create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
char *cond_string,
enum bptype type, enum bpdisp disposition,
- int thread, int ignore_count, int from_tty,
- struct breakpoint *pending_bp)
+ int thread, int ignore_count, int from_tty)
{
int i;
for (i = 0; i < sals.nelts; ++i)
create_breakpoint (expanded, addr_string[i],
cond_string, type, disposition,
- thread, ignore_count, from_tty,
- pending_bp);
+ thread, ignore_count, from_tty);
}
}
{
int i;
for (i = 0; i < sals->nelts; i++)
- {
- resolve_sal_pc (&sals->sals[i]);
-
- /* It's possible for the PC to be nonzero, but still an illegal
- value on some targets.
-
- For example, on HP-UX if you start gdb, and before running the
- inferior you try to set a breakpoint on a shared library function
- "foo" where the inferior doesn't call "foo" directly but does
- pass its address to another function call, then we do find a
- minimal symbol for the "foo", but it's address is invalid.
- (Appears to be an index into a table that the loader sets up
- when the inferior is run.)
-
- Give the target a chance to bless sals.sals[i].pc before we
- try to make a breakpoint for it. */
-#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."));
- else
- error (_("Cannot break on %s without a running program."),
- address);
- }
-#endif
- }
+ resolve_sal_pc (&sals->sals[i]);
}
static void
/* Set a breakpoint according to ARG (function, linenum or *address)
flag: first bit : 0 non-temporary, 1 temporary.
- second bit : 0 normal breakpoint, 1 hardware breakpoint.
-
- PENDING_BP is non-NULL when this function is being called to resolve
- a pending breakpoint. */
+ second bit : 0 normal breakpoint, 1 hardware breakpoint. */
static int
-break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_bp)
+break_command_1 (char *arg, int flag, int from_tty)
{
struct gdb_exception e;
int tempflag, hardwareflag;
switch (e.error)
{
case NOT_FOUND_ERROR:
- /* If called to resolve pending breakpoint, just return
- error code. */
- if (pending_bp)
- return e.reason;
exception_print (gdb_stderr, e);
hardwareflag ? bp_hardware_breakpoint
: bp_breakpoint,
tempflag ? disp_del : disp_donttouch,
- thread, ignore_count, from_tty,
- pending_bp);
+ thread, ignore_count, from_tty);
}
else
{
b->cond_string = cond_string;
b->ignore_count = ignore_count;
b->disposition = tempflag ? disp_del : disp_donttouch;
- b->from_tty = from_tty;
- b->flag = flag;
b->condition_not_parsed = 1;
mention (b);
}
create_breakpoints (sals, addr_string, args->condition,
args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
args->tempflag ? disp_del : disp_donttouch,
- args->thread, args->ignore_count, 0/*from-tty*/,
- NULL/*pending_bp*/);
+ args->thread, args->ignore_count, 0/*from-tty*/);
/* That's it. Discard the cleanups for data inserted into the
breakpoint. */
void
break_command (char *arg, int from_tty)
{
- break_command_1 (arg, 0, from_tty, NULL);
+ break_command_1 (arg, 0, from_tty);
}
void
tbreak_command (char *arg, int from_tty)
{
- break_command_1 (arg, BP_TEMPFLAG, from_tty, NULL);
+ break_command_1 (arg, BP_TEMPFLAG, from_tty);
}
static void
hbreak_command (char *arg, int from_tty)
{
- break_command_1 (arg, BP_HARDWAREFLAG, from_tty, NULL);
+ break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
}
static void
thbreak_command (char *arg, int from_tty)
{
- break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty, NULL);
+ break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
}
static void
if (badInput)
printf_filtered (_("Usage: stop in <function | address>\n"));
else
- break_command_1 (arg, 0, from_tty, NULL);
+ break_command_1 (arg, 0, from_tty);
}
static void
if (badInput)
printf_filtered (_("Usage: stop at <line>\n"));
else
- break_command_1 (arg, 0, from_tty, NULL);
+ break_command_1 (arg, 0, from_tty);
}
/* accessflag: hw_write: watch write,
b->exp_string = exp_string;
b->thread = -1;
b->ops = ops;
- b->from_tty = from_tty;
mention (b);
}
}
}
-/* Used by the gui, could be made a worker for other things. */
-
-struct breakpoint *
-set_breakpoint_sal (struct symtab_and_line sal)
-{
- struct breakpoint *b;
- b = set_raw_breakpoint (sal, bp_breakpoint);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->thread = -1;
- return b;
-}
-
static void
catch_command (char *arg, int from_tty)
{
static void
clear_command (char *arg, int from_tty)
{
- struct breakpoint *b, *tmp, *prev, *found;
+ struct breakpoint *b;
+ VEC(breakpoint_p) *found = 0;
+ int ix;
int default_match;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
1 0 <can't happen> */
sal = sals.sals[i];
- prev = NULL;
- /* Find all matching breakpoints, remove them from the
- breakpoint chain, and add them to the 'found' chain. */
- ALL_BREAKPOINTS_SAFE (b, tmp)
+ /* Find all matching breakpoints and add them to
+ 'found'. */
+ ALL_BREAKPOINTS (b)
{
int match = 0;
/* Are we going to delete b? */
}
if (match)
- {
- /* Remove it from breakpoint_chain... */
- if (b == breakpoint_chain)
- {
- /* b is at the head of the list */
- breakpoint_chain = b->next;
- }
- else
- {
- prev->next = b->next;
- }
- /* And add it to 'found' chain. */
- b->next = found;
- found = b;
- }
- else
- {
- /* Keep b, and keep a pointer to it. */
- prev = b;
- }
+ VEC_safe_push(breakpoint_p, found, b);
}
}
/* Now go thru the 'found' chain and delete them. */
- if (found == 0)
+ if (VEC_empty(breakpoint_p, found))
{
if (arg)
error (_("No breakpoint at %s."), arg);
error (_("No breakpoint at this line."));
}
- if (found->next)
+ if (VEC_length(breakpoint_p, found) > 1)
from_tty = 1; /* Always report if deleted more than one */
if (from_tty)
{
- if (!found->next)
+ if (VEC_length(breakpoint_p, found) == 1)
printf_unfiltered (_("Deleted breakpoint "));
else
printf_unfiltered (_("Deleted breakpoints "));
}
breakpoints_changed ();
- while (found)
+
+ for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
{
if (from_tty)
- printf_unfiltered ("%d ", found->number);
- tmp = found->next;
- delete_breakpoint (found);
- found = tmp;
+ printf_unfiltered ("%d ", b->number);
+ delete_breakpoint (b);
}
if (from_tty)
putchar_unfiltered ('\n');
error (_("Hardware breakpoints used exceeds limit."));
}
- if (bpt->enable_state != bp_permanent)
- bpt->enable_state = bp_enabled;
- bpt->disposition = disposition;
- check_duplicates (bpt);
- breakpoints_changed ();
-
if (bpt->type == bp_watchpoint ||
bpt->type == bp_hardware_watchpoint ||
bpt->type == bp_read_watchpoint ||
printf_filtered (_("\
Cannot enable watchpoint %d because the block in which its expression\n\
is valid is not currently in scope.\n"), bpt->number);
- bpt->enable_state = bp_disabled;
return;
}
select_frame (fr);
}
- value_free (bpt->val);
+ if (bpt->val)
+ value_free (bpt->val);
mark = value_mark ();
bpt->val = evaluate_expression (bpt->exp);
release_value (bpt->val);
printf_filtered (_("\
Cannot enable watchpoint %d because target watch resources\n\
have been allocated for other watchpoints.\n"), bpt->number);
- bpt->enable_state = bp_disabled;
value_free_to_mark (mark);
return;
}
value_free_to_mark (mark);
}
+ if (bpt->enable_state != bp_permanent)
+ bpt->enable_state = bp_enabled;
+ bpt->disposition = disposition;
+ check_duplicates (bpt);
+ breakpoints_changed ();
+
if (deprecated_modify_breakpoint_hook)
deprecated_modify_breakpoint_hook (bpt);
breakpoint_modify_event (bpt->number);