#include "symfile.h"
#include "objfiles.h"
+#include "gdb-events.h"
+
/* Prototypes for local functions. */
+static void until_break_command_continuation (struct continuation_arg *arg);
+
static void
catch_command_1 PARAMS ((char *, int, int));
static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
-static void create_solib_load_unload_event_breakpoint PARAMS ((char *hookname, int tempflag, char *dll_pathname, char *cond_string, enum bptype bp_kind));
+static void solib_load_unload_1 PARAMS ((char *hookname,
+ int tempflag,
+ char *dll_pathname,
+ char *cond_string,
+ enum bptype bp_kind));
-static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag, char *cond_string, enum bptype bp_kind));
+static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag,
+ char *cond_string,
+ enum bptype bp_kind));
-static void break_at_finish_at_depth_command_1 PARAMS ((char *arg, int flag, int from_tty));
+static void break_at_finish_at_depth_command_1 PARAMS ((char *arg,
+ int flag,
+ int from_tty));
-static void break_at_finish_command_1 PARAMS ((char *arg, int flag, int from_tty));
+static void break_at_finish_command_1 PARAMS ((char *arg,
+ int flag,
+ int from_tty));
static void stop_command PARAMS ((char *arg, int from_tty));
static char *ep_parse_optional_filename PARAMS ((char **arg));
-static void catch_exec_command_1 PARAMS ((char *arg, int tempflag, int from_tty));
+static void catch_exec_command_1 PARAMS ((char *arg, int tempflag,
+ int from_tty));
-static void create_exception_catchpoint PARAMS ((int tempflag, char *cond_string, enum exception_event_kind ex_event, struct symtab_and_line * sal));
+static void create_exception_catchpoint
+ PARAMS ((int tempflag, char *cond_string,
+ enum exception_event_kind ex_event,
+ struct symtab_and_line * sal));
-static void catch_exception_command_1 PARAMS ((enum exception_event_kind ex_event, char *arg, int tempflag, int from_tty));
+static void catch_exception_command_1
+ PARAMS ((enum exception_event_kind ex_event,
+ char *arg, int tempflag, int from_tty));
static void tcatch_command PARAMS ((char *arg, int from_tty));
if such is available. */
static int can_use_hw_watchpoints;
-void delete_command PARAMS ((char *, int));
-
void _initialize_breakpoint PARAMS ((void));
void set_breakpoint_count PARAMS ((int));
val = value_of_internalvar (lookup_internalvar (varname));
if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT)
error (
- "Convenience variables used to specify breakpoints must have integer values."
+ "Convenience variables used to specify breakpoints must have integer values."
);
retval = (int) value_as_long (val);
}
if (b->number == bnum)
{
char tmpbuf[128];
- sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum);
+ sprintf (tmpbuf,
+ "Type commands for when breakpoint %d is hit, one per line.",
+ bnum);
l = read_command_lines (tmpbuf, from_tty);
free_command_lines (&b->commands);
b->commands = l;
ALL_BREAKPOINTS (b)
{
if (b->type == bp_none)
- warning ("attempted to read through apparently deleted breakpoint #%d?\n", b->number);
+ warning ("reading through apparently deleted breakpoint #%d?",
+ b->number);
/* memory breakpoint? */
if (b->type == bp_watchpoint
insert_breakpoints ()
{
register struct breakpoint *b, *temp;
+ int return_val = 0; /* return success code. */
int val = 0;
int disabled_breaks = 0;
ALL_BREAKPOINTS_SAFE (b, temp)
{
- if (b->type != bp_watchpoint
+ if (b->enable == permanent)
+ /* Permanent breakpoints cannot be inserted or removed. */
+ continue;
+ else if (b->type != bp_watchpoint
&& b->type != bp_hardware_watchpoint
&& b->type != bp_read_watchpoint
&& b->type != bp_access_watchpoint
if (!disabled_breaks)
{
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr,
- "Cannot insert breakpoint %d:\n", b->number);
- printf_filtered ("Temporarily disabling shared library breakpoints:\n");
+ warning ("Cannot insert breakpoint %d:", b->number);
+ warning ("Temporarily disabling shared library breakpoints:");
}
disabled_breaks = 1;
- printf_filtered ("%d ", b->number);
+ warning ("breakpoint #%d ", b->number);
}
else
#endif
{
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
+ warning ("Cannot insert breakpoint %d:", b->number);
#ifdef ONE_PROCESS_WRITETEXT
- fprintf_unfiltered (gdb_stderr,
- "The same program may be running in another process.\n");
+ warning ("The same program may be running in another process.");
#endif
- memory_error (val, b->address); /* which bombs us out */
+ memory_error (val, b->address); /* which bombs us out */
}
}
else
b->inserted = 1;
+
+ if (val)
+ return_val = val; /* remember failure */
}
else if (ep_is_exception_catchpoint (b)
&& b->enable != disabled
/* If we get here, we must have a callback mechanism for exception
events -- with g++ style embedded label support, we insert
ordinary breakpoints and not catchpoints. */
- sprintf (message, message1, b->number); /* Format possible error message */
+ /* Format possible error message */
+ sprintf (message, message1, b->number);
val = target_insert_breakpoint (b->address, b->shadow_contents);
if (val)
{
/* Couldn't set breakpoint for some reason */
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr,
- "Cannot insert catchpoint %d; disabling it\n", b->number);
+ warning ("Cannot insert catchpoint %d; disabling it.",
+ b->number);
b->enable = disabled;
}
else
/* Bp set, now make sure callbacks are enabled */
int val;
args_for_catchpoint_enable args;
- args.kind = b->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+ args.kind = b->type == bp_catch_catch ?
+ EX_EVENT_CATCH : EX_EVENT_THROW;
args.enable = 1;
val = catch_errors (cover_target_enable_exception_callback,
&args,
{
/* something went wrong */
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d; disabling it\n", b->number);
+ warning ("Cannot insert catchpoint %d; disabling it.",
+ b->number);
b->enable = disabled;
}
}
+
+ if (val)
+ return_val = val; /* remember failure */
}
else if ((b->type == bp_hardware_watchpoint ||
addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
len = TYPE_LENGTH (VALUE_TYPE (v));
- type = 0;
+ type = hw_write;
if (b->type == bp_read_watchpoint)
- type = 1;
+ type = hw_read;
else if (b->type == bp_access_watchpoint)
- type = 2;
+ type = hw_access;
val = target_insert_watchpoint (addr, len, type);
if (val == -1)
/* Failure to insert a watchpoint on any memory value in the
value chain brings us here. */
if (!b->inserted)
- warning ("Hardware watchpoint %d: Could not insert watchpoint\n",
- b->number);
+ {
+ remove_breakpoint (b, mark_uninserted);
+ warning ("Could not insert hardware watchpoint %d.",
+ b->number);
+ val = -1;
+ }
}
else
{
- printf_filtered ("\
-Hardware watchpoint %d deleted because the program has left the block in\n\
-which its expression is valid.\n", b->number);
+ printf_filtered ("Hardware watchpoint %d deleted", b->number);
+ printf_filtered ("because the program has left the block \n");
+ printf_filtered ("in which its expression is valid.\n");
if (b->related_breakpoint)
b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
if ((saved_frame != selected_frame) ||
(saved_level != selected_frame_level))
select_and_print_frame (saved_frame, saved_level);
+
+ if (val)
+ return_val = val; /* remember failure */
}
else if ((b->type == bp_catch_fork
|| b->type == bp_catch_vfork
val = target_insert_exec_catchpoint (inferior_pid);
break;
default:
- warning ("GDB bug: breakpoint.c (insert_breakpoints): enclosing `if' does not protect `switch'");
+ warning ("Internal error, %s line %d.", __FILE__, __LINE__);
break;
}
if (val < 0)
{
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d:\n", b->number);
+ warning ("Cannot insert catchpoint %d.", b->number);
}
else
b->inserted = 1;
+
+ if (val)
+ return_val = val; /* remember failure */
}
}
- if (disabled_breaks)
- printf_filtered ("\n");
- return val;
+ return return_val;
}
int val;
int saved_inferior_pid = inferior_pid;
- inferior_pid = pid; /* Because remove_breakpoint will use this global. */
+ /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
+ inferior_pid = pid; /* Because remove_breakpoint will use this global. */
ALL_BREAKPOINTS (b)
{
if (b->inserted)
won't stop when it ought!
Similarly, we probably ought to keep vfork catchpoints, 'cause
- on this target, we may not be able to stop when the vfork is seen,
- but only when the subsequent exec is seen. (And because deleting
- fork catchpoints here but not vfork catchpoints will seem mysterious
- to users, keep those too.)
+ on this target, we may not be able to stop when the vfork is
+ seen, but only when the subsequent exec is seen. (And because
+ deleting fork catchpoints here but not vfork catchpoints will
+ seem mysterious to users, keep those too.)
??rehrauer: Let's hope that merely clearing out this catchpoint's
target address field, if any, is sufficient to have it be reset
gets 'round to deleting the "use to be a bp_finish" breakpoint.
We really must allow finish_command to delete a bp_finish.
- In the absense of a general solution for the "how do we know it's
- safe to delete something others may have handles to?" problem, what
- we'll do here is just uninsert the bp_finish, and let finish_command
- delete it.
+ In the absense of a general solution for the "how do we know
+ it's safe to delete something others may have handles to?"
+ problem, what we'll do here is just uninsert the bp_finish, and
+ let finish_command delete it.
+
+ (We know the bp_finish is "doomed" in the sense that it's
+ momentary, and will be deleted as soon as finish_command sees
+ the inferior stopped. So it doesn't matter that the bp's
+ address is probably bogus in the new a.out, unlike e.g., the
+ solib breakpoints.) */
- (We know the bp_finish is "doomed" in the sense that it's momentary,
- and will be deleted as soon as finish_command sees the inferior stopped.
- So it doesn't matter that the bp's address is probably bogus in the
- new a.out, unlike e.g., the solib breakpoints.) */
if (b->type == bp_finish)
{
continue;
if (pid == inferior_pid)
error ("Cannot detach breakpoints of inferior_pid");
- inferior_pid = pid; /* Because remove_breakpoint will use this global. */
+ /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
+ inferior_pid = pid; /* Because remove_breakpoint will use this global. */
ALL_BREAKPOINTS (b)
{
if (b->inserted)
{
int val;
+ if (b->enable == permanent)
+ /* Permanent breakpoints cannot be inserted or removed. */
+ return 0;
+
if (b->type == bp_none)
- warning ("attempted to remove apparently deleted breakpoint #%d?\n", b->number);
+ warning ("attempted to remove apparently deleted breakpoint #%d?",
+ b->number);
if (b->type != bp_watchpoint
&& b->type != bp_hardware_watchpoint
&& b->type != bp_catch_exec
&& b->type != bp_catch_catch
&& b->type != bp_catch_throw)
-
{
if (b->type == bp_hardware_breakpoint)
val = target_remove_hw_breakpoint (b->address, b->shadow_contents);
addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
len = TYPE_LENGTH (VALUE_TYPE (v));
- type = 0;
+ type = hw_write;
if (b->type == bp_read_watchpoint)
- type = 1;
+ type = hw_read;
else if (b->type == bp_access_watchpoint)
- type = 2;
+ type = hw_access;
val = target_remove_watchpoint (addr, len, type);
if (val == -1)
}
/* Failure to remove any of the hardware watchpoints comes here. */
if ((is == mark_uninserted) && (b->inserted))
- warning ("Hardware watchpoint %d: Could not remove watchpoint\n",
+ warning ("Could not remove hardware watchpoint %d.",
b->number);
/* Free the saved value chain. We will construct a new one
val = target_remove_exec_catchpoint (inferior_pid);
break;
default:
- warning ("GDB bug: breakpoint.c (remove_breakpoint): enclosing `if' does not protect `switch'");
+ warning ("Internal error, %s line %d.", __FILE__, __LINE__);
break;
}
if (val)
b->inserted = 0;
}
-/* Clear the "inserted" flag in all breakpoints and delete any breakpoints
- which should go away between runs of the program.
+/* Clear the "inserted" flag in all breakpoints and delete any
+ breakpoints which should go away between runs of the program.
Plus other such housekeeping that has to be done for breakpoints
between runs.
- Note: this function gets called at the end of a run (by generic_mourn_inferior)
- and when a run begins (by init_wait_for_inferior). */
+ Note: this function gets called at the end of a run (by
+ generic_mourn_inferior) and when a run begins (by
+ init_wait_for_inferior). */
/* Don't issue the warning unless it's really needed... */
if (warning_needed && (context != inf_exited))
{
- warning ("Exception catchpoints from last run were deleted, you must reinsert them explicitly");
+ warning ("Exception catchpoints from last run were deleted.");
+ warning ("You must reinsert them explicitly.");
warning_needed = 0;
}
}
-/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC.
- When continuing from a location with a breakpoint,
- we actually single step once before calling insert_breakpoints. */
+/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
+ exists at PC. It returns ordinary_breakpoint_here if it's an
+ ordinary breakpoint, or permanent_breakpoint_here if it's a
+ permanent breakpoint.
+ - When continuing from a location with an ordinary breakpoint, we
+ actually single step once before calling insert_breakpoints.
+ - When continuing from a localion with a permanent breakpoint, we
+ need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
+ the target, to advance the PC past the breakpoint. */
-int
+enum breakpoint_here
breakpoint_here_p (pc)
CORE_ADDR pc;
{
register struct breakpoint *b;
+ int any_breakpoint_here = 0;
ALL_BREAKPOINTS (b)
- if (b->enable == enabled
- && b->enable != shlib_disabled
- && b->enable != call_disabled
+ if ((b->enable == enabled
+ || b->enable == permanent)
&& b->address == pc) /* bp is enabled and matches pc */
- {
- if (overlay_debugging &&
- section_is_overlay (b->section) &&
- !section_is_mapped (b->section))
- continue; /* unmapped overlay -- can't be a match */
- else
- return 1;
- }
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else if (b->enable == permanent)
+ return permanent_breakpoint_here;
+ else
+ any_breakpoint_here = 1;
+ }
- return 0;
+ return any_breakpoint_here ? ordinary_breakpoint_here : 0;
}
-/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(), but it
- only returns true if there is actually a breakpoint inserted at PC. */
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(),
+ but it only returns true if there is actually a breakpoint inserted
+ at PC. */
int
breakpoint_inserted_here_p (pc)
return 0;
}
-/* Return nonzero if FRAME is a dummy frame. We can't use PC_IN_CALL_DUMMY
- because figuring out the saved SP would take too much time, at least using
- get_saved_register on the 68k. This means that for this function to
- work right a port must use the bp_call_dummy breakpoint. */
+/* Return nonzero if FRAME is a dummy frame. We can't use
+ PC_IN_CALL_DUMMY because figuring out the saved SP would take too
+ much time, at least using get_saved_register on the 68k. This
+ means that for this function to work right a port must use the
+ bp_call_dummy breakpoint. */
int
frame_in_dummy (frame)
printf_filtered ("forked");
else if (bs->breakpoint_at->type == bp_catch_vfork)
printf_filtered ("vforked");
- printf_filtered (" process %d), ", bs->breakpoint_at->forked_inferior_pid);
+ printf_filtered (" process %d), ",
+ bs->breakpoint_at->forked_inferior_pid);
return 0;
}
else if (bs->breakpoint_at->type == bp_catch_exec)
}
else if (bs->breakpoint_at->type == bp_catch_catch)
{
- if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
+ if (current_exception_event &&
+ (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
{
annotate_catchpoint (bs->breakpoint_at->number);
- printf_filtered ("\nCatchpoint %d (exception caught), ", bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception caught), ",
+ bs->breakpoint_at->number);
printf_filtered ("throw location ");
if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
printf_filtered ("%s:%d",
printf_filtered ("unknown");
printf_filtered ("\n");
- return 1; /* don't bother to print location frame info */
+ return 1; /* don't bother to print location frame info */
}
else
{
- return -1; /* really throw, some other bpstat will handle it */
+ return -1; /* really throw, some other bpstat will handle it */
}
}
else if (bs->breakpoint_at->type == bp_catch_throw)
{
- if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
+ if (current_exception_event &&
+ (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
{
annotate_catchpoint (bs->breakpoint_at->number);
- printf_filtered ("\nCatchpoint %d (exception thrown), ", bs->breakpoint_at->number);
+ printf_filtered ("\nCatchpoint %d (exception thrown), ",
+ bs->breakpoint_at->number);
printf_filtered ("throw location ");
if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE)
printf_filtered ("%s:%d",
printf_filtered ("unknown");
printf_filtered ("\n");
- return 1; /* don't bother to print location frame info */
+ return 1; /* don't bother to print location frame info */
}
else
{
- return -1; /* really catch, some other bpstat willhandle it */
+ return -1; /* really catch, some other bpstat willhandle it */
}
}
printf_filtered ("\n");
return -1;
}
- /* We can't deal with it. Maybe another member of the bpstat chain can. */
+ /* We can't deal with it.
+ Maybe another member of the bpstat chain can. */
return -1;
}
return val;
/* Maybe another breakpoint in the chain caused us to stop.
- (Currently all watchpoints go on the bpstat whether hit or
- not. That probably could (should) be changed, provided care is taken
+ (Currently all watchpoints go on the bpstat whether hit or not.
+ That probably could (should) be changed, provided care is taken
with respect to bpstat_explains_signal). */
if (bs->next)
return bpstat_print (bs->next);
#if defined(SOLIB_HAVE_LOAD_EVENT)
&& (!SOLIB_HAVE_LOAD_EVENT (inferior_pid)
|| ((b->dll_pathname != NULL)
- && (strcmp (b->dll_pathname, SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid)) != 0)))
+ && (strcmp (b->dll_pathname,
+ SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid))
+ != 0)))
#endif
)
continue;
#if defined(SOLIB_HAVE_UNLOAD_EVENT)
&& (!SOLIB_HAVE_UNLOAD_EVENT (inferior_pid)
|| ((b->dll_pathname != NULL)
- && (strcmp (b->dll_pathname, SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid)) != 0)))
+ && (strcmp (b->dll_pathname,
+ SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid))
+ != 0)))
#endif
)
continue;
bs->print = 1;
sprintf (message, message1, b->number);
- if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
+ if (b->type == bp_watchpoint ||
+ b->type == bp_hardware_watchpoint)
{
- switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
+ switch (catch_errors (watchpoint_check, bs, message,
+ RETURN_MASK_ALL))
{
case WP_DELETED:
/* We've already printed what needs to be printed. */
break;
}
}
- else if (b->type == bp_read_watchpoint || b->type == bp_access_watchpoint)
+ else if (b->type == bp_read_watchpoint ||
+ b->type == bp_access_watchpoint)
{
CORE_ADDR addr;
value_ptr v;
CORE_ADDR vaddr;
vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- if (addr == vaddr)
+ /* Exact match not required. Within range is sufficient.
+ */
+ if (addr >= vaddr &&
+ addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
found = 1;
}
}
if (found)
- switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL))
+ switch (catch_errors (watchpoint_check, bs, message,
+ RETURN_MASK_ALL))
{
case WP_DELETED:
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
break;
}
+ else /* found == 0 */
+ {
+ /* This is a case where some watchpoint(s) triggered,
+ but not at the address of this watchpoint (FOUND
+ was left zero). So don't print anything for this
+ watchpoint. */
+ bs->print_it = print_it_noop;
+ bs->stop = 0;
+ continue;
+ }
}
else
{
as bp_silent and wp_noisy is the same as bp_noisy. That is because
after stopping, the check for whether to step over a breakpoint
(BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
- reference to how we stopped. We retain separate wp_silent and bp_silent
- codes in case we want to change that someday.
+ reference to how we stopped. We retain separate wp_silent and
+ bp_silent codes in case we want to change that someday.
Another possibly interesting property of this table is that
there's a partial ordering, priority-like, of the actions. Once
bs_class = wp_silent;
}
else
- /* There was a watchpoint, but we're not stopping. This requires
- no further action. */
+ /* There was a watchpoint, but we're not stopping.
+ This requires no further action. */
bs_class = no_effect;
break;
case bp_longjmp:
bs_class = bp_silent;
}
else
- /* There was a catchpoint, but we're not stopping. This requires
- no further action. */
+ /* There was a catchpoint, but we're not stopping.
+ This requires no further action. */
bs_class = no_effect;
break;
case bp_catch_catch:
bs_class = bs->print ? bp_noisy : bp_silent;
break;
case bp_call_dummy:
- /* Make sure the action is stop (silent or noisy), so infrun.c
- pops the dummy frame. */
+ /* Make sure the action is stop (silent or noisy),
+ so infrun.c pops the dummy frame. */
bs_class = bp_silent;
retval.call_dummy = 1;
break;
if ((ep->type != bp_catch_load) &&
(ep->type != bp_catch_unload) &&
(ep->type != bp_catch_catch) &&
- (ep->type != bp_catch_throw)) /* pai: (temp) ADD fork/vfork here!! */
+ (ep->type != bp_catch_throw))
+ /* pai: (temp) ADD fork/vfork here!! */
continue;
/* Yes; add it to the list. */
#endif
if (dll_pathname)
{
- ep->triggered_dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1);
+ ep->triggered_dll_pathname = (char *)
+ xmalloc (strlen (dll_pathname) + 1);
strcpy (ep->triggered_dll_pathname, dll_pathname);
}
else
static char *bpdisps[] =
{"del", "dstp", "dis", "keep"};
- static char bpenables[] = "nyn";
+ static char bpenables[] = "nynny";
char wrap_indent[80];
+
ALL_BREAKPOINTS (b)
if (bnum == -1
|| bnum == b->number)
printf_filtered
("%d%s%s ",
b->number,
- ((b->enable == disabled || b->enable == shlib_disabled || b->enable == call_disabled)
- ? " (disabled)" : ""),
+ ((b->enable == disabled ||
+ b->enable == shlib_disabled ||
+ b->enable == call_disabled) ? " (disabled)"
+ : b->enable == permanent ? " (permanent)"
+ : ""),
(others > 1) ? "," : ((others == 1) ? " and" : ""));
}
printf_filtered ("also set at pc ");
/* Rescan breakpoints at address ADDRESS,
marking the first one as "first" and any others as "duplicates".
- This is so that the bpt instruction is only inserted once. */
+ This is so that the bpt instruction is only inserted once.
+ If we have a permanent breakpoint at ADDRESS, make that one
+ the official one, and the rest as duplicates. */
static void
check_duplicates (address, section)
{
register struct breakpoint *b;
register int count = 0;
+ struct breakpoint *perm_bp = 0;
if (address == 0) /* Watchpoints are uninteresting */
return;
&& b->address == address
&& (overlay_debugging == 0 || b->section == section))
{
+ /* Have we found a permanent breakpoint? */
+ if (b->enable == permanent)
+ {
+ perm_bp = b;
+ break;
+ }
+
count++;
b->duplicate = count > 1;
}
+
+ /* If we found a permanent breakpoint at this address, go over the
+ list again and declare all the other breakpoints there to be the
+ duplicates. */
+ if (perm_bp)
+ {
+ perm_bp->duplicate = 0;
+
+ /* Permanent breakpoint should always be inserted. */
+ if (! perm_bp->inserted)
+ internal_error ("allegedly permanent breakpoint is not "
+ "actually inserted");
+
+ ALL_BREAKPOINTS (b)
+ if (b != perm_bp)
+ {
+ if (b->inserted)
+ internal_error ("another breakpoint was inserted on top of "
+ "a permanent breakpoint");
+
+ if (b->enable != disabled
+ && b->enable != shlib_disabled
+ && b->enable != call_disabled
+ && b->address == address
+ && (overlay_debugging == 0 || b->section == section))
+ b->duplicate = 1;
+ }
+ }
}
/* Low level routine to set a breakpoint.
return b;
}
+
+/* Note that the breakpoint object B describes a permanent breakpoint
+ instruction, hard-wired into the inferior's code. */
+void
+make_breakpoint_permanent (struct breakpoint *b)
+{
+ b->enable = permanent;
+
+ /* By definition, permanent breakpoints are already present in the code. */
+ b->inserted = 1;
+}
+
#ifdef GET_LONGJMP_TARGET
static void
{
struct minimal_symbol *m;
- m = lookup_minimal_symbol_text (func_name, NULL, (struct objfile *) NULL);
+ m = lookup_minimal_symbol_text (func_name, NULL,
+ (struct objfile *) NULL);
if (m)
sal.pc = SYMBOL_VALUE_ADDRESS (m);
else
#endif /* #ifdef GET_LONGJMP_TARGET */
-/* Call this routine when stepping and nexting to enable a breakpoint if we do
- a longjmp(). When we hit that breakpoint, call
+/* Call this routine when stepping and nexting to enable a breakpoint
+ if we do a longjmp(). When we hit that breakpoint, call
set_longjmp_resume_breakpoint() to figure out where we are going. */
void
delete_breakpoint (b);
}
-void
+struct breakpoint *
create_solib_event_breakpoint (address)
CORE_ADDR address;
{
b->number = internal_breakpoint_number--;
b->disposition = donttouch;
b->type = bp_shlib_event;
+
+ return b;
}
+/* Disable any breakpoints that are on code in shared libraries. Only
+ apply to enabled breakpoints, disabled ones can just stay disabled. */
+
void
disable_breakpoints_in_shlibs (silent)
int silent;
#if defined (PC_SOLIB)
if (((b->type == bp_breakpoint) ||
(b->type == bp_hardware_breakpoint)) &&
- (b->enable != shlib_disabled) &&
- (b->enable != call_disabled) &&
+ b->enable == enabled &&
!b->duplicate &&
PC_SOLIB (b->address))
{
if (!disabled_shlib_breaks)
{
target_terminal_ours_for_output ();
- printf_filtered ("Temporarily disabling shared library breakpoints:\n");
+ warning ("Temporarily disabling shared library breakpoints:");
}
disabled_shlib_breaks = 1;
- printf_filtered ("%d ", b->number);
+ warning ("breakpoint #%d ", b->number);
}
}
#endif
}
- if (disabled_shlib_breaks && !silent)
- printf_filtered ("\n");
}
/* Try to reenable any breakpoints in shared libraries. */
#endif
static void
-create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string, bp_kind)
+solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
char *hookname;
int tempflag;
char *dll_pathname;
{
struct breakpoint *b;
struct symtabs_and_lines sals;
- struct symtab_and_line sal;
struct cleanup *old_chain;
struct cleanup *canonical_strings_chain = NULL;
- int i;
char *addr_start = hookname;
char *addr_end = NULL;
char **canonical = (char **) NULL;
}
if (sals.nelts != 1)
{
- warning ("Unable to set a unique breakpoint on dynamic linker callback.");
+ warning ("Unable to set unique breakpoint on dynamic linker callback.");
warning ("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. */
+ /* Make sure that all storage allocated in decode_line_1 gets freed
+ in case the following errors out. */
old_chain = make_cleanup (free, sals.sals);
if (canonical != (char **) NULL)
{
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->cond = NULL;
- b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
b->thread = thread;
if (canonical != (char **) NULL && canonical[0] != NULL)
}
void
-create_solib_load_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
+create_solib_load_event_breakpoint (hookname, tempflag,
+ dll_pathname, cond_string)
char *hookname;
int tempflag;
char *dll_pathname;
char *cond_string;
{
- create_solib_load_unload_event_breakpoint (hookname,
- tempflag,
- dll_pathname,
- cond_string,
- bp_catch_load);
+ solib_load_unload_1 (hookname, tempflag, dll_pathname,
+ cond_string, bp_catch_load);
}
void
-create_solib_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string)
+create_solib_unload_event_breakpoint (hookname, tempflag,
+ dll_pathname, cond_string)
char *hookname;
int tempflag;
char *dll_pathname;
char *cond_string;
{
- create_solib_load_unload_event_breakpoint (hookname,
- tempflag,
- dll_pathname,
- cond_string,
- bp_catch_unload);
+ solib_load_unload_1 (hookname,tempflag, dll_pathname,
+ cond_string, bp_catch_unload);
}
static void
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->cond = NULL;
- b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
b->thread = thread;
b->addr_string = NULL;
b->enable = enabled;
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->cond = NULL;
- b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
b->thread = thread;
b->addr_string = NULL;
b->enable = enabled;
return i;
}
-/* Call this after hitting the longjmp() breakpoint. Use this to set a new
- breakpoint at the target of the jmp_buf.
+/* Call this after hitting the longjmp() breakpoint. Use this to set
+ a new breakpoint at the target of the jmp_buf.
- FIXME - This ought to be done by setting a temporary breakpoint that gets
- deleted automatically... */
+ FIXME - This ought to be done by setting a temporary breakpoint
+ that gets deleted automatically... */
void
set_longjmp_resume_breakpoint (pc, frame)
delete_breakpoint_hook and so on. */
if (create_breakpoint_hook)
create_breakpoint_hook (b);
+ breakpoint_create_event (b->number);
switch (b->type)
{
print_expression (b->exp, gdb_stdout);
break;
case bp_access_watchpoint:
- printf_filtered ("Hardware access (read/write) watchpoint %d: ", b->number);
+ printf_filtered ("Hardware access (read/write) watchpoint %d: ",
+ b->number);
print_expression (b->exp, gdb_stdout);
break;
case bp_breakpoint:
printf_filtered ("Catchpoint %d (%s %s)",
b->number,
(b->type == bp_catch_load) ? "load" : "unload",
- (b->dll_pathname != NULL) ? b->dll_pathname : "<any library>");
+ (b->dll_pathname != NULL) ?
+ b->dll_pathname : "<any library>");
break;
case bp_catch_fork:
case bp_catch_vfork:
if (!sals.nelts)
return;
- /* Make sure that all storage allocated in decode_line_1 gets freed in case
- the following `for' loop errors out. */
+ /* Make sure that all storage allocated in decode_line_1 gets freed
+ in case the following `for' loop errors out. */
old_chain = make_cleanup (free, sals.sals);
if (canonical != (char **) NULL)
{
try to make a breakpoint for it. */
if (PC_REQUIRES_RUN_BEFORE_USE (sals.sals[i].pc))
{
- error ("Cannot break on %s without a running program.", addr_start);
+ error ("Cannot break on %s without a running program.",
+ addr_start);
}
tok = arg;
int i, target_resources_ok;
i = hw_breakpoint_used_count ();
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
- bp_hardware_breakpoint, i + sals.nelts, 0);
+ target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
+ i + sals.nelts, 0);
if (target_resources_ok == 0)
error ("No hardware breakpoint support in the target.");
else if (target_resources_ok < 0)
if (sals.nelts > 1)
{
- printf_filtered ("Multiple breakpoints were set.\n");
- printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
}
do_cleanups (old_chain);
}
{
addr_string = (char *) xmalloc (26 + extra_args_len);
if (extra_args_len)
- sprintf (addr_string, "*0x%x %s", high, extra_args);
+ sprintf (addr_string, "*0x%s %s", paddr_nz (high), extra_args);
else
- sprintf (addr_string, "*0x%x", high);
+ sprintf (addr_string, "*0x%s", paddr_nz (high));
break_command_1 (addr_string, flag, from_tty);
free (addr_string);
}
if (selected_frame)
{
addr_string = (char *) xmalloc (15);
- sprintf (addr_string, "*0x%x", selected_frame->pc);
+ sprintf (addr_string, "*0x%s", paddr_nz (selected_frame->pc));
if (arg)
if_arg = 1;
}
{
break_string = (char *) xmalloc (extra_args_len + 26);
if (extra_args_len)
- sprintf (break_string, "*0x%x %s", high, extra_args);
+ sprintf (break_string, "*0x%s %s", paddr_nz (high), extra_args);
else
- sprintf (break_string, "*0x%x", high);
+ sprintf (break_string, "*0x%s", paddr_nz (high));
break_command_1 (break_string, flag, from_tty);
free (break_string);
}
}
if (sals.nelts > 1)
{
- printf_filtered ("Multiple breakpoints were set.\n");
- printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+ warning ("Multiple breakpoints were set.\n");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
}
do_cleanups (old_chain);
}
char *argptr = arg;
int hasColon = 0;
- /* look for a ':'. If this is a line number specification, then say
- it is bad, otherwise, it should be an address or function/method
- name */
+ /* look for a ':'. If this is a line number specification, then
+ say it is bad, otherwise, it should be an address or
+ function/method name */
while (*argptr && !hasColon)
{
hasColon = (*argptr == ':');
}
/* ARGSUSED */
-/* accessflag: 0: watch write, 1: watch read, 2: watch access(read or write) */
+/* accessflag: hw_write: watch write,
+ hw_read: watch read,
+ hw_access: watch access (read or write) */
static void
watch_command_1 (arg, accessflag, from_tty)
char *arg;
if (*tok)
error ("Junk at end of command.");
- if (accessflag == 1)
+ if (accessflag == hw_read)
bp_type = bp_read_watchpoint;
- else if (accessflag == 2)
+ else if (accessflag == hw_access)
bp_type = bp_access_watchpoint;
else
bp_type = bp_hardware_watchpoint;
if (mem_cnt != 0)
{
i = hw_watchpoint_used_count (bp_type, &other_type_used);
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
- bp_type, i + mem_cnt, other_type_used);
+ target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_type, i + mem_cnt,
+ other_type_used);
if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint)
- error ("Target does not have this type of hardware watchpoint support.");
+ error ("Target does not support this type of hardware watchpoint.");
+
if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint)
- error ("Target resources have been allocated for other types of watchpoints.");
+ error ("Target can only support one kind of HW watchpoint at a time.");
}
#if defined(HPUXHPPA)
in hardware return zero. */
#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
-#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_size) \
- ((byte_size) <= (REGISTER_SIZE))
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \
+ ((BYTE_SIZE) <= (REGISTER_SIZE))
+#endif
+
+#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \
+ TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN)
#endif
static int
{
if (v->lval == lval_memory)
{
- if (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (TYPE_LENGTH (VALUE_TYPE (v))))
+ CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ int len = TYPE_LENGTH (VALUE_TYPE (v));
+
+ if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+ return 0;
+ else
found_memory_cnt++;
}
else if (v->lval != not_lval && v->modifiable == 0)
- return 0;
+ return 0; /* ??? What does this represent? */
+ else if (v->lval == lval_register)
+ return 0; /* cannot watch a register with a HW watchpoint */
}
/* The expression itself looks suitable for using a hardware
char *arg;
int from_tty;
{
- watch_command_1 (arg, 0, from_tty);
+ watch_command_1 (arg, hw_write, from_tty);
}
static void
char *arg;
int from_tty;
{
- watch_command_1 (arg, 1, from_tty);
+ watch_command_1 (arg, hw_read, from_tty);
}
static void
char *arg;
int from_tty;
{
- watch_command_1 (arg, 2, from_tty);
+ watch_command_1 (arg, hw_access, from_tty);
}
\f
cmd_continuation pointer, to complete the until command. It takes
care of cleaning up the temporary breakpoints set up by the until
command. */
-void
-until_break_command_continuation (arg)
- struct continuation_arg *arg;
+static void
+until_break_command_continuation (struct continuation_arg *arg)
{
/* Do all the exec cleanups, which at this point should only be the
one set up in the first part of the until_break_command
struct frame_info *prev_frame = get_prev_frame (selected_frame);
struct breakpoint *breakpoint;
struct cleanup *old_chain;
- struct continuation_arg *arg1, *arg2;
clear_proceed_status ();
sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
default_breakpoint_line, (char ***) NULL);
else
- sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, (char ***) NULL);
+ sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
+ 0, (char ***) NULL);
if (sals.nelts != 1)
error ("Couldn't get information on specified line.");
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
if (!async_p || !target_has_async)
- old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+ old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint,
+ breakpoint);
else
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
struct sal_chain *next = (struct sal_chain *)
alloca (sizeof (struct sal_chain));
next->next = sal_chain;
- next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0);
+ next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym),
+ 0);
sal_chain = next;
}
}
that might be an event name in the leading characters. If a
possible match is found, a pointer to the last character of
the token is returned. Else, NULL is returned. */
+
static char *
ep_find_event_name_end (arg)
char *arg;
attempt to evaluate the string against a particular block.) And,
it updates arg to point to the first character following the parsed
if clause in the arg string. */
+
static char *
ep_parse_optional_if_clause (arg)
char **arg;
}
catch_fork_kind;
-static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind, char *arg, int tempflag, int from_tty));
+static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind,
+ char *arg,
+ int tempflag,
+ int from_tty));
static void
catch_fork_command_1 (fork_kind, arg, tempflag, from_tty)
/* Create a load breakpoint that only triggers when a load of
the specified dll (or any dll, if no pathname was specified)
occurs. */
- SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+ SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag,
+ dll_pathname, cond_string);
}
static void
/* Create an unload breakpoint that only triggers when an unload of
the specified dll (or any dll, if no pathname was specified)
occurs. */
- SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string);
+ SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag,
+ dll_pathname, cond_string);
}
#endif /* SOLIB_ADD */
struct symtab_and_line *sal;
{
struct breakpoint *b;
- int i;
int thread = -1; /* All threads. */
if (!sal) /* no exception support? */
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->cond = NULL;
- b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string));
+ b->cond_string = (cond_string == NULL) ?
+ NULL : savestring (cond_string, strlen (cond_string));
b->thread = thread;
b->addr_string = NULL;
b->enable = enabled;
if (sal != (struct symtab_and_line *) -1)
create_exception_catchpoint (tempflag, cond_string, ex_event, sal);
else
- return; /* something went wrong with setting up callbacks */
+ return; /* something went wrong with setting up callbacks */
}
else
{
{
/* Set a breakpoint on __raise_exception () */
- fprintf_filtered (gdb_stderr, "Unsupported with this platform/compiler combination.\n");
- fprintf_filtered (gdb_stderr, "Perhaps you can achieve the effect you want by setting\n");
- fprintf_filtered (gdb_stderr, "a breakpoint on __raise_exception().\n");
+ warning ("Unsupported with this platform/compiler combination.");
+ warning ("Perhaps you can achieve the effect you want by setting");
+ warning ("a breakpoint on __raise_exception().");
}
}
}
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
- b->type = bp_breakpoint; /* Important -- this is an ordinary breakpoint.
- For platforms with callback support for exceptions,
- create_exception_catchpoint() will create special
- bp types (bp_catch_catch and bp_catch_throw), and
- there is code in insert_breakpoints() and elsewhere
- that depends on that. */
+
+ /* Important -- this is an ordinary breakpoint. For platforms
+ with callback support for exceptions,
+ create_exception_catchpoint() will create special bp types
+ (bp_catch_catch and bp_catch_throw), and there is code in
+ insert_breakpoints() and elsewhere that depends on that. */
+ b->type = bp_breakpoint;
b->cond = cond;
b->enable = enabled;
if (sals.nelts > 1)
{
- printf_unfiltered ("Multiple breakpoints were set.\n");
- printf_unfiltered ("Use the \"delete\" command to delete unwanted breakpoints.\n");
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
}
free ((PTR) sals.sals);
}
}
else if (strncmp (arg1_start, "catch", arg1_length) == 0)
{
- catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1, tempflag, from_tty);
+ catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1,
+ tempflag, from_tty);
}
else if (strncmp (arg1_start, "throw", arg1_length) == 0)
{
- catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1, tempflag, from_tty);
+ catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1,
+ tempflag, from_tty);
}
else if (strncmp (arg1_start, "thread_start", arg1_length) == 0)
{
}
}
-/* Delete a breakpoint and clean up all traces of it in the data structures. */
+/* Delete a breakpoint and clean up all traces of it in the data
+ structures. */
void
delete_breakpoint (bpt)
if (delete_breakpoint_hook)
delete_breakpoint_hook (bpt);
+ breakpoint_delete_event (bpt->number);
if (bpt->inserted)
remove_breakpoint (bpt, mark_uninserted);
static char message[sizeof (message1) + 30];
args_for_catchpoint_enable args;
- sprintf (message, message1, bpt->number); /* Format possible error msg */
- args.kind = bpt->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW;
+ /* Format possible error msg */
+ sprintf (message, message1, bpt->number);
+ args.kind = bpt->type == bp_catch_catch ?
+ EX_EVENT_CATCH : EX_EVENT_THROW;
args.enable = 0;
catch_errors (cover_target_enable_exception_callback, &args,
message, RETURN_MASK_ALL);
&& b->enable != call_disabled)
{
int val;
- val = target_insert_breakpoint (b->address, b->shadow_contents);
+
+ /* We should never reach this point if there is a permanent
+ breakpoint at the same address as the one being deleted.
+ If there is a permanent breakpoint somewhere, it should
+ always be the only one inserted. */
+ if (b->enable == permanent)
+ internal_error ("another breakpoint was inserted on top of "
+ "a permanent breakpoint");
+
+ if (b->type == bp_hardware_breakpoint)
+ val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+ else
+ val = target_insert_breakpoint (b->address, b->shadow_contents);
+
if (val != 0)
{
target_terminal_ours_for_output ();
- fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number);
+ warning ("Cannot insert breakpoint %d:", b->number);
memory_error (val, b->address); /* which bombs us out */
}
else
breakpoint_re_set_one (bint)
PTR bint;
{
- struct breakpoint *b = (struct breakpoint *) bint; /* get past catch_errs */
+ /* get past catch_errs */
+ struct breakpoint *b = (struct breakpoint *) bint;
struct value *mark;
int i;
struct symtabs_and_lines sals;
switch (b->type)
{
case bp_none:
- warning ("attempted to reset apparently deleted breakpoint #%d?\n", b->number);
+ warning ("attempted to reset apparently deleted breakpoint #%d?",
+ b->number);
return 0;
case bp_breakpoint:
case bp_hardware_breakpoint:
case bp_read_watchpoint:
case bp_access_watchpoint:
innermost_block = NULL;
- /* The issue arises of what context to evaluate this in. The same
- one as when it was set, but what does that mean when symbols have
- been re-read? We could save the filename and functionname, but
- if the context is more local than that, the best we could do would
- be something like how many levels deep and which index at that
- particular level, but that's going to be less stable than filenames
- or functionnames. */
+ /* The issue arises of what context to evaluate this in. The
+ same one as when it was set, but what does that mean when
+ symbols have been re-read? We could save the filename and
+ functionname, but if the context is more local than that, the
+ best we could do would be something like how many levels deep
+ and which index at that particular level, but that's going to
+ be less stable than filenames or function names. */
+
/* So for now, just use a global context. */
if (b->exp)
free ((PTR) b->exp);
save_input_radix = input_radix;
ALL_BREAKPOINTS_SAFE (b, temp)
{
- sprintf (message, message1, b->number); /* Format possible error msg */
+ /* Format possible error msg */
+ sprintf (message, message1, b->number);
catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
}
set_language (save_language);
if (bpt->type == bp_watchpoint_scope)
return;
+ /* You can't disable permanent breakpoints. */
+ if (bpt->enable == permanent)
+ return;
+
bpt->enable = disabled;
check_duplicates (bpt->address, bpt->section);
if (modify_breakpoint_hook)
modify_breakpoint_hook (bpt);
+ breakpoint_modify_event (bpt->number);
}
/* ARGSUSED */
switch (bpt->type)
{
case bp_none:
- warning ("attempted to disable apparently deleted breakpoint #%d?\n", bpt->number);
+ warning ("attempted to disable apparently deleted breakpoint #%d?",
+ bpt->number);
continue;
case bp_breakpoint:
case bp_catch_load:
{
int i;
i = hw_breakpoint_used_count ();
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
- bp_hardware_breakpoint, i + 1, 0);
+ target_resources_ok =
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
+ i + 1, 0);
if (target_resources_ok == 0)
error ("No hardware breakpoint support in the target.");
else if (target_resources_ok < 0)
error ("Hardware breakpoints used exceeds limit.");
}
- bpt->enable = enabled;
+ if (bpt->enable != permanent)
+ bpt->enable = enabled;
bpt->disposition = disposition;
check_duplicates (bpt->address, bpt->section);
breakpoints_changed ();
- if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||
- bpt->type == bp_read_watchpoint || bpt->type == bp_access_watchpoint)
+ if (bpt->type == bp_watchpoint ||
+ bpt->type == bp_hardware_watchpoint ||
+ bpt->type == bp_read_watchpoint ||
+ bpt->type == bp_access_watchpoint)
{
if (bpt->exp_valid_block != NULL)
{
}
if (save_selected_frame_level >= 0)
- select_and_print_frame (save_selected_frame, save_selected_frame_level);
+ select_and_print_frame (save_selected_frame,
+ save_selected_frame_level);
value_free_to_mark (mark);
}
if (modify_breakpoint_hook)
modify_breakpoint_hook (bpt);
+ breakpoint_modify_event (bpt->number);
}
void
switch (bpt->type)
{
case bp_none:
- warning ("attempted to enable apparently deleted breakpoint #%d?\n", bpt->number);
+ warning ("attempted to enable apparently deleted breakpoint #%d?",
+ bpt->number);
continue;
case bp_breakpoint:
case bp_catch_load:
error ("Empty line specification.");
if (default_breakpoint_valid)
sals = decode_line_1 (&string, funfirstline,
- default_breakpoint_symtab, default_breakpoint_line,
+ default_breakpoint_symtab,
+ default_breakpoint_line,
(char ***) NULL);
else
sals = decode_line_1 (&string, funfirstline,
by using \"enable delete\" on the catchpoint number.");
add_com ("watch", class_breakpoint, watch_command,
-
"Set a watchpoint for an expression.\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression changes.");