#include "top.h"
#include "valprint.h"
#include "jit.h"
-#include "xml-syscall.h"
#include "parser-defs.h"
#include "gdb_regex.h"
#include "probe.h"
static void insert_breakpoint_locations (void);
-static int syscall_catchpoint_p (struct breakpoint *b);
-
static void tracepoints_info (char *, int);
static void delete_trace_command (char *, int);
}
void
-set_breakpoint_condition (struct breakpoint *b, char *exp,
+set_breakpoint_condition (struct breakpoint *b, const char *exp,
int from_tty)
{
xfree (b->cond_string);
struct gdbarch *frame_arch = get_frame_arch (fi);
CORE_ADDR frame_pc = get_frame_pc (fi);
- /* If we're in a function epilogue, unwinding may not work
- properly, so do not attempt to recreate locations at this
+ /* If we're at a point where the stack has been destroyed
+ (e.g. in a function epilogue), unwinding may not work
+ properly. Do not attempt to recreate locations at this
point. See similar comments in watchpoint_check. */
- if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
+ if (gdbarch_stack_frame_destroyed_p (frame_arch, frame_pc))
return;
/* Save the current frame's ID so we can restore it after
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
- if (bl->permanent)
- /* Permanent breakpoints cannot be inserted or removed. */
- return 0;
-
/* The type of none suggests that owner is actually deleted.
This should not ever happen. */
gdb_assert (bl->owner->type != bp_none);
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
- if (bl->permanent)
- /* Permanent breakpoints cannot be inserted or removed. */
- return 0;
-
/* The type of none suggests that owner is actually deleted.
This should not ever happen. */
gdb_assert (bl->owner->type != bp_none);
struct bp_location *bl, **blp_tmp;
ALL_BP_LOCATIONS (bl, blp_tmp)
- if (bl->pspace == current_program_space
- && !bl->permanent)
+ if (bl->pspace == current_program_space)
bl->inserted = 0;
}
static int
command_line_is_silent (struct command_line *cmd)
{
- return cmd && (strcmp ("silent", cmd->line) == 0
- || (xdb_commands && strcmp ("Q", cmd->line) == 0));
+ return cmd && (strcmp ("silent", cmd->line) == 0);
}
/* Execute all the commands associated with all the breakpoints at
struct gdbarch *frame_arch = get_frame_arch (frame);
CORE_ADDR frame_pc = get_frame_pc (frame);
- /* in_function_epilogue_p() returns a non-zero value if we're
+ /* stack_frame_destroyed_p() returns a non-zero value if we're
still in the function but the stack frame has already been
invalidated. Since we can't rely on the values of local
variables after the stack has been destroyed, we are treating
frame is in an epilogue - even if they are in some other
frame, our view of the stack is likely to be wrong and
frame_find_by_id could error out. */
- if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
+ if (gdbarch_stack_frame_destroyed_p (frame_arch, frame_pc))
return WP_IGNORE;
fr = frame_find_by_id (b->watchpoint_frame);
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)
-{
- struct bp_location *bl;
-
- /* By definition, permanent breakpoints are already present in the
- code. Mark all locations as inserted. For now,
- make_breakpoint_permanent is called in just one place, so it's
- hard to say if it's reasonable to have permanent breakpoint with
- multiple locations or not, but it's easy to implement. */
- for (bl = b->loc; bl; bl = bl->next)
- {
- bl->permanent = 1;
- bl->inserted = 1;
- }
-}
-
/* Call this routine when stepping and nexting to enable a breakpoint
if we do a longjmp() or 'throw' in TP. FRAME is the frame which
initiated the operation. */
catch_load_or_unload (arg, from_tty, 0, command);
}
-/* An instance of this type is used to represent a syscall catchpoint.
- It includes a "struct breakpoint" as a kind of base class; users
- downcast to "struct breakpoint *" when needed. A breakpoint is
- really of this type iff its ops pointer points to
- CATCH_SYSCALL_BREAKPOINT_OPS. */
-
-struct syscall_catchpoint
-{
- /* The base class. */
- struct breakpoint base;
-
- /* Syscall numbers used for the 'catch syscall' feature. If no
- syscall has been specified for filtering, its value is NULL.
- Otherwise, it holds a list of all syscalls to be caught. The
- list elements are allocated with xmalloc. */
- VEC(int) *syscalls_to_be_caught;
-};
-
-/* Implement the "dtor" breakpoint_ops method for syscall
- catchpoints. */
-
-static void
-dtor_catch_syscall (struct breakpoint *b)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
-
- VEC_free (int, c->syscalls_to_be_caught);
-
- base_breakpoint_ops.dtor (b);
-}
-
-static const struct inferior_data *catch_syscall_inferior_data = NULL;
-
-struct catch_syscall_inferior_data
-{
- /* We keep a count of the number of times the user has requested a
- particular syscall to be tracked, and pass this information to the
- target. This lets capable targets implement filtering directly. */
-
- /* Number of times that "any" syscall is requested. */
- int any_syscall_count;
-
- /* Count of each system call. */
- VEC(int) *syscalls_counts;
-
- /* This counts all syscall catch requests, so we can readily determine
- if any catching is necessary. */
- int total_syscalls_count;
-};
-
-static struct catch_syscall_inferior_data*
-get_catch_syscall_inferior_data (struct inferior *inf)
-{
- struct catch_syscall_inferior_data *inf_data;
-
- inf_data = inferior_data (inf, catch_syscall_inferior_data);
- if (inf_data == NULL)
- {
- inf_data = XCNEW (struct catch_syscall_inferior_data);
- set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
- }
-
- return inf_data;
-}
-
-static void
-catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
-{
- xfree (arg);
-}
-
-
-/* Implement the "insert" breakpoint_ops method for syscall
- catchpoints. */
-
-static int
-insert_catch_syscall (struct bp_location *bl)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
- struct inferior *inf = current_inferior ();
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
-
- ++inf_data->total_syscalls_count;
- if (!c->syscalls_to_be_caught)
- ++inf_data->any_syscall_count;
- else
- {
- int i, iter;
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- int elem;
-
- if (iter >= VEC_length (int, inf_data->syscalls_counts))
- {
- int old_size = VEC_length (int, inf_data->syscalls_counts);
- uintptr_t vec_addr_offset
- = old_size * ((uintptr_t) sizeof (int));
- uintptr_t vec_addr;
- VEC_safe_grow (int, inf_data->syscalls_counts, iter + 1);
- vec_addr = ((uintptr_t) VEC_address (int,
- inf_data->syscalls_counts)
- + vec_addr_offset);
- memset ((void *) vec_addr, 0,
- (iter + 1 - old_size) * sizeof (int));
- }
- elem = VEC_index (int, inf_data->syscalls_counts, iter);
- VEC_replace (int, inf_data->syscalls_counts, iter, ++elem);
- }
- }
-
- return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
- inf_data->total_syscalls_count != 0,
- inf_data->any_syscall_count,
- VEC_length (int,
- inf_data->syscalls_counts),
- VEC_address (int,
- inf_data->syscalls_counts));
-}
-
-/* Implement the "remove" breakpoint_ops method for syscall
- catchpoints. */
-
-static int
-remove_catch_syscall (struct bp_location *bl)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
- struct inferior *inf = current_inferior ();
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
-
- --inf_data->total_syscalls_count;
- if (!c->syscalls_to_be_caught)
- --inf_data->any_syscall_count;
- else
- {
- int i, iter;
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- int elem;
- if (iter >= VEC_length (int, inf_data->syscalls_counts))
- /* Shouldn't happen. */
- continue;
- elem = VEC_index (int, inf_data->syscalls_counts, iter);
- VEC_replace (int, inf_data->syscalls_counts, iter, --elem);
- }
- }
-
- return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
- inf_data->total_syscalls_count != 0,
- inf_data->any_syscall_count,
- VEC_length (int,
- inf_data->syscalls_counts),
- VEC_address (int,
- inf_data->syscalls_counts));
-}
-
-/* Implement the "breakpoint_hit" breakpoint_ops method for syscall
- catchpoints. */
-
-static int
-breakpoint_hit_catch_syscall (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
-{
- /* We must check if we are catching specific syscalls in this
- breakpoint. If we are, then we must guarantee that the called
- syscall is the same syscall we are catching. */
- int syscall_number = 0;
- const struct syscall_catchpoint *c
- = (const struct syscall_catchpoint *) bl->owner;
-
- if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
- && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
- return 0;
-
- syscall_number = ws->value.syscall_number;
-
- /* Now, checking if the syscall is the same. */
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- if (syscall_number == iter)
- return 1;
-
- return 0;
- }
-
- return 1;
-}
-
-/* Implement the "print_it" breakpoint_ops method for syscall
- catchpoints. */
-
-static enum print_stop_action
-print_it_catch_syscall (bpstat bs)
-{
- struct ui_out *uiout = current_uiout;
- struct breakpoint *b = bs->breakpoint_at;
- /* These are needed because we want to know in which state a
- syscall is. It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
- or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we
- must print "called syscall" or "returned from syscall". */
- ptid_t ptid;
- struct target_waitstatus last;
- struct syscall s;
- struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
-
- get_last_target_status (&ptid, &last);
-
- get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
-
- annotate_catchpoint (b->number);
-
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
- ? EXEC_ASYNC_SYSCALL_ENTRY
- : EXEC_ASYNC_SYSCALL_RETURN));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
-
- if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
- ui_out_text (uiout, " (call to syscall ");
- else
- ui_out_text (uiout, " (returned from syscall ");
-
- if (s.name == NULL || ui_out_is_mi_like_p (uiout))
- ui_out_field_int (uiout, "syscall-number", last.value.syscall_number);
- if (s.name != NULL)
- ui_out_field_string (uiout, "syscall-name", s.name);
-
- ui_out_text (uiout, "), ");
-
- return PRINT_SRC_AND_LOC;
-}
-
-/* Implement the "print_one" breakpoint_ops method for syscall
- catchpoints. */
-
-static void
-print_one_catch_syscall (struct breakpoint *b,
- struct bp_location **last_loc)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- struct gdbarch *gdbarch = b->loc->gdbarch;
-
- get_user_print_options (&opts);
- /* Field 4, the address, is omitted (which makes the columns not
- line up too nicely with the headers, but the effect is relatively
- readable). */
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
-
- if (c->syscalls_to_be_caught
- && VEC_length (int, c->syscalls_to_be_caught) > 1)
- ui_out_text (uiout, "syscalls \"");
- else
- ui_out_text (uiout, "syscall \"");
-
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- char *text = xstrprintf ("%s", "");
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- char *x = text;
- struct syscall s;
- get_syscall_by_number (gdbarch, iter, &s);
-
- if (s.name != NULL)
- text = xstrprintf ("%s%s, ", text, s.name);
- else
- text = xstrprintf ("%s%d, ", text, iter);
-
- /* We have to xfree the last 'text' (now stored at 'x')
- because xstrprintf dynamically allocates new space for it
- on every call. */
- xfree (x);
- }
- /* Remove the last comma. */
- text[strlen (text) - 2] = '\0';
- ui_out_field_string (uiout, "what", text);
- }
- else
- ui_out_field_string (uiout, "what", "<any syscall>");
- ui_out_text (uiout, "\" ");
-
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type", "syscall");
-}
-
-/* Implement the "print_mention" breakpoint_ops method for syscall
- catchpoints. */
-
-static void
-print_mention_catch_syscall (struct breakpoint *b)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct gdbarch *gdbarch = b->loc->gdbarch;
-
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
-
- if (VEC_length (int, c->syscalls_to_be_caught) > 1)
- printf_filtered (_("Catchpoint %d (syscalls"), b->number);
- else
- printf_filtered (_("Catchpoint %d (syscall"), b->number);
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- struct syscall s;
- get_syscall_by_number (gdbarch, iter, &s);
-
- if (s.name)
- printf_filtered (" '%s' [%d]", s.name, s.number);
- else
- printf_filtered (" %d", s.number);
- }
- printf_filtered (")");
- }
- else
- printf_filtered (_("Catchpoint %d (any syscall)"),
- b->number);
-}
-
-/* Implement the "print_recreate" breakpoint_ops method for syscall
- catchpoints. */
-
-static void
-print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
-{
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct gdbarch *gdbarch = b->loc->gdbarch;
-
- fprintf_unfiltered (fp, "catch syscall");
-
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
-
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- struct syscall s;
-
- get_syscall_by_number (gdbarch, iter, &s);
- if (s.name)
- fprintf_unfiltered (fp, " %s", s.name);
- else
- fprintf_unfiltered (fp, " %d", s.number);
- }
- }
- print_recreate_thread (b, fp);
-}
-
-/* The breakpoint_ops structure to be used in syscall catchpoints. */
-
-static struct breakpoint_ops catch_syscall_breakpoint_ops;
-
-/* Returns non-zero if 'b' is a syscall catchpoint. */
-
-static int
-syscall_catchpoint_p (struct breakpoint *b)
-{
- return (b->ops == &catch_syscall_breakpoint_ops);
-}
-
/* Initialize a new breakpoint of the bp_catchpoint kind. If TEMPFLAG
is non-zero, then make the breakpoint temporary. If COND_STRING is
not NULL, then store it in the breakpoint. OPS, if not NULL, is
static struct breakpoint_ops catch_exec_breakpoint_ops;
-static void
-create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
- const struct breakpoint_ops *ops)
-{
- struct syscall_catchpoint *c;
- struct gdbarch *gdbarch = get_current_arch ();
-
- c = XNEW (struct syscall_catchpoint);
- init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
- c->syscalls_to_be_caught = filter;
-
- install_breakpoint (0, &c->base, 1);
-}
-
static int
hw_breakpoint_used_count (void)
{
set_breakpoint_location_function (loc,
sal->explicit_pc || sal->explicit_line);
+ /* While by definition, permanent breakpoints are already present in the
+ code, we don't mark the location as inserted. Normally one would expect
+ that GDB could rely on that breakpoint instruction to stop the program,
+ thus removing the need to insert its own breakpoint, except that executing
+ the breakpoint instruction can kill the target instead of reporting a
+ SIGTRAP. E.g., on SPARC, when interrupts are disabled, executing the
+ instruction resets the CPU, so QEMU 2.0.0 for SPARC correspondingly dies
+ with "Trap 0x02 while interrupts disabled, Error state". Letting the
+ breakpoint be inserted normally results in QEMU knowing about the GDB
+ breakpoint, and thus trap before the breakpoint instruction is executed.
+ (If GDB later needs to continue execution past the permanent breakpoint,
+ it manually increments the PC, thus avoiding executing the breakpoint
+ instruction.) */
if (bp_loc_is_permanent (loc))
- {
- loc->inserted = 1;
- loc->permanent = 1;
- }
+ loc->permanent = 1;
return loc;
}
gdb_assert (loc != NULL);
- /* bp_call_dummy breakpoint locations are usually memory locations
- where GDB just wrote a breakpoint instruction, making it look
- as if there is a permanent breakpoint at that location. Considering
- it permanent makes GDB rely on that breakpoint instruction to stop
- the program, thus removing the need to insert its own breakpoint
- there. This is normally expected to work, except that some versions
- of QEMU (Eg: QEMU 2.0.0 for SPARC) just report a fatal problem (Trap
- 0x02 while interrupts disabled, Error state) instead of reporting
- a SIGTRAP. QEMU should probably be fixed, but in the interest of
- compatibility with versions that behave this way, we always consider
- bp_call_dummy breakpoint locations as non-permanent. */
- if (loc->owner->type == bp_call_dummy)
- return 0;
-
cleanup = save_current_space_and_thread ();
switch_to_program_space_and_thread (loc->pspace);
struct command_line *printf_cmd_line
= xmalloc (sizeof (struct command_line));
- printf_cmd_line = xmalloc (sizeof (struct command_line));
printf_cmd_line->control_type = simple_control;
printf_cmd_line->body_count = 0;
printf_cmd_line->body_list = NULL;
{
/* If no arg given, or if first arg is 'if ', use the default
breakpoint. */
- if ((*address) == NULL
- || (startswith ((*address), "if") && isspace ((*address)[2])))
+ if ((*address) == NULL || linespec_lexer_lex_keyword (*address))
{
/* The last displayed codepoint, if it's valid, is our default breakpoint
address. */
associated with SAL. */
if (sarch == NULL)
sarch = gdbarch;
- rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal->pc,
- NULL, &msg);
+ rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal->pc, &msg);
old_chain = make_cleanup (xfree, msg);
if (!rslt)
b->addr_string = copy_arg;
if (parse_arg)
- b->cond_string = NULL;
+ {
+ b->cond_string = NULL;
+ b->extra_string = NULL;
+ }
else
{
/* Create a private copy of condition string. */
cond_string = xstrdup (cond_string);
make_cleanup (xfree, cond_string);
}
+ /* Create a private copy of any extra string. */
+ if (extra_string != NULL)
+ {
+ extra_string = xstrdup (extra_string);
+ make_cleanup (xfree, extra_string);
+ }
b->cond_string = cond_string;
+ b->extra_string = extra_string;
+ b->thread = thread;
}
- b->extra_string = NULL;
b->ignore_count = ignore_count;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->condition_not_parsed = 1;
stack_frame_id, bp_until);
make_cleanup_delete_breakpoint (breakpoint);
- proceed (-1, GDB_SIGNAL_DEFAULT, 0);
+ proceed (-1, GDB_SIGNAL_DEFAULT);
/* If we are running asynchronously, and proceed call above has
actually managed to start the target, arrange for breakpoints to
b->language = language_ada;
}
-/* Splits the argument using space as delimiter. Returns an xmalloc'd
- filter list, or NULL if no filtering is required. */
-static VEC(int) *
-catch_syscall_split_args (char *arg)
-{
- VEC(int) *result = NULL;
- struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
- struct gdbarch *gdbarch = target_gdbarch ();
-
- while (*arg != '\0')
- {
- int i, syscall_number;
- char *endptr;
- char cur_name[128];
- struct syscall s;
-
- /* Skip whitespace. */
- arg = skip_spaces (arg);
-
- for (i = 0; i < 127 && arg[i] && !isspace (arg[i]); ++i)
- cur_name[i] = arg[i];
- cur_name[i] = '\0';
- arg += i;
-
- /* Check if the user provided a syscall name or a number. */
- syscall_number = (int) strtol (cur_name, &endptr, 0);
- if (*endptr == '\0')
- get_syscall_by_number (gdbarch, syscall_number, &s);
- else
- {
- /* We have a name. Let's check if it's valid and convert it
- to a number. */
- get_syscall_by_name (gdbarch, cur_name, &s);
-
- if (s.number == UNKNOWN_SYSCALL)
- /* Here we have to issue an error instead of a warning,
- because GDB cannot do anything useful if there's no
- syscall number to be caught. */
- error (_("Unknown syscall name '%s'."), cur_name);
- }
-
- /* Ok, it's valid. */
- VEC_safe_push (int, result, s.number);
- }
-
- discard_cleanups (cleanup);
- return result;
-}
-
-/* Implement the "catch syscall" command. */
-
-static void
-catch_syscall_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
-{
- int tempflag;
- VEC(int) *filter;
- struct syscall s;
- struct gdbarch *gdbarch = get_current_arch ();
-
- /* Checking if the feature if supported. */
- if (gdbarch_get_syscall_number_p (gdbarch) == 0)
- error (_("The feature 'catch syscall' is not supported on \
-this architecture yet."));
-
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
- arg = skip_spaces (arg);
-
- /* We need to do this first "dummy" translation in order
- to get the syscall XML file loaded or, most important,
- to display a warning to the user if there's no XML file
- for his/her architecture. */
- get_syscall_by_number (gdbarch, 0, &s);
-
- /* The allowed syntax is:
- catch syscall
- catch syscall <name | number> [<name | number> ... <name | number>]
-
- Let's check if there's a syscall name. */
-
- if (arg != NULL)
- filter = catch_syscall_split_args (arg);
- else
- filter = NULL;
-
- create_syscall_event_catchpoint (tempflag, filter,
- &catch_syscall_breakpoint_ops);
-}
-
static void
catch_command (char *arg, int from_tty)
{
continue;
}
- /* Permanent breakpoint should always be inserted. */
- if (loc->permanent && ! loc->inserted)
- internal_error (__FILE__, __LINE__,
- _("allegedly permanent breakpoint is not "
- "actually inserted"));
-
if (b->type == bp_hardware_watchpoint)
loc_first_p = &wp_loc_first;
else if (b->type == bp_read_watchpoint)
/* Clear the condition modification flag. */
loc->condition_changed = condition_unchanged;
-
- if (loc->inserted && !loc->permanent
- && (*loc_first_p)->permanent)
- internal_error (__FILE__, __LINE__,
- _("another breakpoint was inserted on top of "
- "a permanent breakpoint"));
}
if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ())
return 0;
}
-/* Returns 0 if 'bp' is NOT a syscall catchpoint,
- non-zero otherwise. */
-static int
-is_syscall_catchpoint_enabled (struct breakpoint *bp)
-{
- if (syscall_catchpoint_p (bp)
- && bp->enable_state != bp_disabled
- && bp->enable_state != bp_call_disabled)
- return 1;
- else
- return 0;
-}
-
-int
-catch_syscall_enabled (void)
-{
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (current_inferior ());
-
- return inf_data->total_syscalls_count != 0;
-}
-
-int
-catching_syscall_number (int syscall_number)
-{
- struct breakpoint *bp;
-
- ALL_BREAKPOINTS (bp)
- if (is_syscall_catchpoint_enabled (bp))
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bp;
-
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- if (syscall_number == iter)
- return 1;
- }
- else
- return 1;
- }
-
- return 0;
-}
-
-/* Complete syscall names. Used by "catch syscall". */
-static VEC (char_ptr) *
-catch_syscall_completer (struct cmd_list_element *cmd,
- const char *text, const char *word)
-{
- const char **list = get_syscall_names (get_current_arch ());
- VEC (char_ptr) *retlist
- = (list == NULL) ? NULL : complete_on_enum (list, word, word);
-
- xfree (list);
- return retlist;
-}
-
/* Tracepoint-specific operations. */
/* Set tracepoint count to NUM. */
set_cmd_completer (command, completer);
}
-static void
-clear_syscall_counts (struct inferior *inf)
-{
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
-
- inf_data->total_syscalls_count = 0;
- inf_data->any_syscall_count = 0;
- VEC_free (int, inf_data->syscalls_counts);
-}
-
static void
save_command (char *arg, int from_tty)
{
ops->print_mention = print_mention_catch_exec;
ops->print_recreate = print_recreate_catch_exec;
- /* Syscall catchpoints. */
- ops = &catch_syscall_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->dtor = dtor_catch_syscall;
- ops->insert_location = insert_catch_syscall;
- ops->remove_location = remove_catch_syscall;
- ops->breakpoint_hit = breakpoint_hit_catch_syscall;
- ops->print_it = print_it_catch_syscall;
- ops->print_one = print_one_catch_syscall;
- ops->print_mention = print_mention_catch_syscall;
- ops->print_recreate = print_recreate_catch_syscall;
-
/* Solib-related catchpoints. */
ops = &catch_solib_breakpoint_ops;
*ops = base_breakpoint_ops;
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
- observer_attach_inferior_exit (clear_syscall_counts);
observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
breakpoint_objfile_key
= register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
- catch_syscall_inferior_data
- = register_inferior_data_with_cleanup (NULL,
- catch_syscall_inferior_data_cleanup);
-
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
before a breakpoint is set. */
add_com ("ignore", class_breakpoint, ignore_command, _("\
Set ignore-count of breakpoint number N to COUNT.\n\
Usage is `ignore N COUNT'."));
- if (xdb_commands)
- add_com_alias ("bc", "ignore", class_breakpoint, 1);
add_com ("commands", class_breakpoint, commands_command, _("\
Set commands to be executed when a breakpoint is hit.\n\
This is used to cancel the effect of the \"disable\" command.\n\
With a subcommand you can enable temporarily."),
&enablelist, "enable ", 1, &cmdlist);
- if (xdb_commands)
- add_com ("ab", class_breakpoint, enable_command, _("\
-Enable some breakpoints.\n\
-Give breakpoint numbers (separated by spaces) as arguments.\n\
-With no subcommand, breakpoints are enabled until you command otherwise.\n\
-This is used to cancel the effect of the \"disable\" command.\n\
-With a subcommand you can enable temporarily."));
add_com_alias ("en", "enable", class_breakpoint, 1);
&disablelist, "disable ", 1, &cmdlist);
add_com_alias ("dis", "disable", class_breakpoint, 1);
add_com_alias ("disa", "disable", class_breakpoint, 1);
- if (xdb_commands)
- add_com ("sb", class_breakpoint, disable_command, _("\
-Disable some breakpoints.\n\
-Arguments are breakpoint numbers with spaces in between.\n\
-To disable all breakpoints, give no argument.\n\
-A disabled breakpoint is not forgotten, but has no effect until re-enabled."));
add_cmd ("breakpoints", class_alias, disable_command, _("\
Disable some breakpoints.\n\
&deletelist, "delete ", 1, &cmdlist);
add_com_alias ("d", "delete", class_breakpoint, 1);
add_com_alias ("del", "delete", class_breakpoint, 1);
- if (xdb_commands)
- add_com ("db", class_breakpoint, delete_command, _("\
-Delete some breakpoints.\n\
-Arguments are breakpoint numbers with spaces in between.\n\
-To delete all breakpoints, give no argument.\n"));
add_cmd ("breakpoints", class_alias, delete_command, _("\
Delete some breakpoints or auto-display expressions.\n\
add_com_alias ("bre", "break", class_run, 1);
add_com_alias ("brea", "break", class_run, 1);
- if (xdb_commands)
- add_com_alias ("ba", "break", class_breakpoint, 1);
-
if (dbx_commands)
{
add_abbrev_prefix_cmd ("stop", class_breakpoint, stop_command, _("\
add_info_alias ("b", "breakpoints", 1);
- if (xdb_commands)
- add_com ("lb", class_breakpoint, breakpoints_info, _("\
-Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
-The \"Type\" column indicates one of:\n\
-\tbreakpoint - normal breakpoint\n\
-\twatchpoint - watchpoint\n\
-The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
-the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
-breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
-address and file/line number respectively.\n\
-\n\
-Convenience variable \"$_\" and default examine address for \"x\"\n\
-are set to the address of the last breakpoint listed unless the command\n\
-is prefixed with \"server \".\n\n\
-Convenience variable \"$bpnum\" contains the number of the last\n\
-breakpoint set."));
-
add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints, _("\
Status of all breakpoints, or breakpoint number NUMBER.\n\
The \"Type\" column indicates one of:\n\
NULL,
CATCH_PERMANENT,
CATCH_TEMPORARY);
- add_catch_command ("syscall", _("\
-Catch system calls by their names and/or numbers.\n\
-Arguments say which system calls to catch. If no arguments\n\
-are given, every system call will be caught.\n\
-Arguments, if given, should be one or more system call names\n\
-(if your system supports that), or system call numbers."),
- catch_syscall_command_1,
- catch_syscall_completer,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
c = add_com ("watch", class_breakpoint, watch_command, _("\
Set a watchpoint for an expression.\n\