/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2012 Free Software Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
This file is part of GDB.
#include "mi/mi-common.h"
#include "python/python.h"
+/* Enums for exception-handling support. */
+enum exception_event_kind
+{
+ EX_EVENT_THROW,
+ EX_EVENT_CATCH
+};
+
/* Prototypes for local functions. */
static void enable_delete_command (char *, int);
static int strace_marker_p (struct breakpoint *b);
-static void init_catchpoint (struct breakpoint *b,
- struct gdbarch *gdbarch, int tempflag,
- char *cond_string,
- const struct breakpoint_ops *ops);
-
/* The abstract base class all breakpoint_ops structures inherit
from. */
-static struct breakpoint_ops base_breakpoint_ops;
+struct breakpoint_ops base_breakpoint_ops;
/* The breakpoint_ops structure to be inherited by all breakpoint_ops
that are implemented on top of software or hardware breakpoints
}
mark_breakpoint_modified (b);
- annotate_breakpoints_changed ();
observer_notify_breakpoint_modified (b);
}
decref_counted_command_line (&b->commands);
b->commands = alloc_counted_command_line (commands);
- annotate_breakpoints_changed ();
observer_notify_breakpoint_modified (b);
}
incref_counted_command_line (info->cmd);
decref_counted_command_line (&b->commands);
b->commands = info->cmd;
- annotate_breakpoints_changed ();
observer_notify_breakpoint_modified (b);
}
}
return NULL;
}
+/* See breakpoint.h. */
+
+enum bpstat_signal_value
+bpstat_explains_signal (bpstat bsp)
+{
+ enum bpstat_signal_value result = BPSTAT_SIGNAL_NO;
+
+ for (; bsp != NULL; bsp = bsp->next)
+ {
+ /* Ensure that, if we ever entered this loop, then we at least
+ return BPSTAT_SIGNAL_HIDE. */
+ enum bpstat_signal_value newval = BPSTAT_SIGNAL_HIDE;
+
+ if (bsp->breakpoint_at != NULL)
+ newval = bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at);
+
+ if (newval > result)
+ result = newval;
+ }
+
+ return result;
+}
+
/* Put in *NUM the breakpoint number of the first breakpoint we are
stopped at. *BSP upon return is a bpstat which points to the
remaining breakpoints stopped at (but which is not guaranteed to be
else if (b->ignore_count > 0)
{
b->ignore_count--;
- annotate_ignore_count_change ();
bs->stop = 0;
/* Increase the hit count even though we don't stop. */
++(b->hit_count);
struct symtab_and_line sal = find_pc_line (loc->address, 0);
const char *fullname = symtab_to_fullname (sal.symtab);
- if (fullname)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}
ui_out_field_int (uiout, "line", loc->line_number);
return bptypes[(int) type].description;
}
+DEF_VEC_I(int);
+
+/* For MI, output a field named 'thread-groups' with a list as the value.
+ For CLI, prefix the list with the string 'inf'. */
+
+static void
+output_thread_groups (struct ui_out *uiout,
+ const char *field_name,
+ VEC(int) *inf_num,
+ int mi_only)
+{
+ struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (uiout,
+ field_name);
+ int is_mi = ui_out_is_mi_like_p (uiout);
+ int inf;
+ int i;
+
+ /* For backward compatibility, don't display inferiors in CLI unless
+ there are several. Always display them for MI. */
+ if (!is_mi && mi_only)
+ return;
+
+ for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
+ {
+ if (is_mi)
+ {
+ char mi_group[10];
+
+ xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
+ ui_out_field_string (uiout, NULL, mi_group);
+ }
+ else
+ {
+ if (i == 0)
+ ui_out_text (uiout, " inf ");
+ else
+ ui_out_text (uiout, ", ");
+
+ ui_out_text (uiout, plongest (inf));
+ }
+ }
+
+ do_cleanups (back_to);
+}
+
/* Print B to gdb_stdout. */
static void
}
- /* For backward compatibility, don't display inferiors unless there
- are several. */
- if (loc != NULL
- && !header_of_multiple
- && (allflag
- || (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && (number_of_program_spaces () > 1
- || number_of_inferiors () > 1)
- /* LOC is for existing B, it cannot be in
- moribund_locations and thus having NULL OWNER. */
- && loc->owner->type != bp_catchpoint)))
+ if (loc != NULL && !header_of_multiple)
{
struct inferior *inf;
- int first = 1;
+ VEC(int) *inf_num = NULL;
+ int mi_only = 1;
- for (inf = inferior_list; inf != NULL; inf = inf->next)
+ ALL_INFERIORS (inf)
{
if (inf->pspace == loc->pspace)
- {
- if (first)
- {
- first = 0;
- ui_out_text (uiout, " inf ");
- }
- else
- ui_out_text (uiout, ", ");
- ui_out_text (uiout, plongest (inf->num));
- }
+ VEC_safe_push (int, inf_num, inf->num);
}
+
+ /* For backward compatibility, don't display inferiors in CLI unless
+ there are several. Always display for MI. */
+ if (allflag
+ || (!gdbarch_has_global_breakpoints (target_gdbarch ())
+ && (number_of_program_spaces () > 1
+ || number_of_inferiors () > 1)
+ /* LOC is for existing B, it cannot be in
+ moribund_locations and thus having NULL OWNER. */
+ && loc->owner->type != bp_catchpoint))
+ mi_only = 0;
+ output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
+ VEC_free (int, inf_num);
}
if (!part_of_multiple)
ui_out_text (uiout, " bytes\n");
}
}
-
- if (!part_of_multiple && b->extra_string
- && b->type == bp_dprintf && !b->commands)
- {
- annotate_field (7);
- ui_out_text (uiout, "\t(agent printf) ");
- ui_out_field_string (uiout, "printf", b->extra_string);
- ui_out_text (uiout, "\n");
- }
l = b->commands ? b->commands->commands : NULL;
if (!part_of_multiple && l)
ui_out_field_int (uiout, "pass", t->pass_count);
ui_out_text (uiout, " \n");
}
+
+ /* Don't display it when tracepoint or tracepoint location is
+ pending. */
+ if (!header_of_multiple && loc != NULL && !loc->shlib_disabled)
+ {
+ annotate_field (11);
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "installed",
+ loc->inserted ? "y" : "n");
+ else
+ {
+ if (loc->inserted)
+ ui_out_text (uiout, "\t");
+ else
+ ui_out_text (uiout, "\tnot ");
+ ui_out_text (uiout, "installed on target\n");
+ }
+ }
}
if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
program space. */
if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
b->pspace = sal.pspace;
-
- annotate_breakpoints_changed ();
}
/* set_raw_breakpoint is a low level routine for allocating and
ptid_get_pid (c->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type", "fork");
}
/* Implement the "print_mention" breakpoint_ops method for fork
ptid_get_pid (c->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type", "vfork");
}
/* Implement the "print_mention" breakpoint_ops method for vfork
}
ui_out_field_string (uiout, "what", msg);
xfree (msg);
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type",
+ self->is_load ? "load" : "unload");
}
static void
catch_load_or_unload (arg, from_tty, 0, command);
}
-DEF_VEC_I(int);
-
/* 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
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
not NULL, then store it in the breakpoint. OPS, if not NULL, is
the breakpoint_ops structure associated to the catchpoint. */
-static void
+void
init_catchpoint (struct breakpoint *b,
struct gdbarch *gdbarch, int tempflag,
char *cond_string,
ui_out_field_string (uiout, "what", c->exec_pathname);
ui_out_text (uiout, "\" ");
}
+
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type", "exec");
}
static void
internal_error (__FILE__, __LINE__,
_("Invalid dprintf style."));
+ gdb_assert (printf_line != NULL);
/* Manufacture a printf/continue sequence. */
- if (printf_line)
- {
- struct command_line *printf_cmd_line, *cont_cmd_line = NULL;
+ {
+ struct command_line *printf_cmd_line, *cont_cmd_line = NULL;
- if (strcmp (dprintf_style, dprintf_style_agent) != 0)
- {
- cont_cmd_line = xmalloc (sizeof (struct command_line));
- cont_cmd_line->control_type = simple_control;
- cont_cmd_line->body_count = 0;
- cont_cmd_line->body_list = NULL;
- cont_cmd_line->next = NULL;
- cont_cmd_line->line = xstrdup ("continue");
- }
+ if (strcmp (dprintf_style, dprintf_style_agent) != 0)
+ {
+ cont_cmd_line = xmalloc (sizeof (struct command_line));
+ cont_cmd_line->control_type = simple_control;
+ cont_cmd_line->body_count = 0;
+ cont_cmd_line->body_list = NULL;
+ cont_cmd_line->next = NULL;
+ cont_cmd_line->line = xstrdup ("continue");
+ }
- 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;
- printf_cmd_line->next = cont_cmd_line;
- printf_cmd_line->line = printf_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;
+ printf_cmd_line->next = cont_cmd_line;
+ printf_cmd_line->line = printf_line;
- breakpoint_set_commands (b, printf_cmd_line);
- }
+ breakpoint_set_commands (b, printf_cmd_line);
+ }
}
/* Update all dprintf commands, making their command lists reflect
break_command_1 (arg, 0, from_tty);
}
-void dprintf_command (char *arg, int from_tty);
-
/* The dynamic printf command is mostly like a regular breakpoint, but
with a prewired command list consisting of a single output command,
built from extra arguments supplied on the dprintf command
line. */
-void
+static void
dprintf_command (char *arg, int from_tty)
{
create_breakpoint (get_current_arch (),
if (b->loc)
*last_loc = b->loc;
if (strstr (b->addr_string, "throw") != NULL)
- ui_out_field_string (uiout, "what", "exception throw");
+ {
+ ui_out_field_string (uiout, "what", "exception throw");
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type", "throw");
+ }
else
- ui_out_field_string (uiout, "what", "exception catch");
+ {
+ ui_out_field_string (uiout, "what", "exception catch");
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string (uiout, "catch-type", "catch");
+ }
}
static void
make_cleanup (VEC_cleanup (breakpoint_p), &found);
for (i = 0; i < sals.nelts; i++)
{
- int is_abs, sal_name_len;
+ int is_abs;
/* If exact pc given, clear bpts at that pc.
If line given (pc == 0), clear all bpts on specified line.
sal = sals.sals[i];
is_abs = sal.symtab == NULL ? 1 : IS_ABSOLUTE_PATH (sal.symtab->filename);
- sal_name_len = is_abs ? 0 : strlen (sal.symtab->filename);
/* Find all matching breakpoints and add them to 'found'. */
ALL_BREAKPOINTS (b)
line_match = 1;
else if (!IS_ABSOLUTE_PATH (sal.symtab->filename)
&& compare_filenames_for_search (loc->source_file,
- sal.symtab->filename,
- sal_name_len))
+ sal.symtab->filename))
line_match = 1;
}
else
printf_unfiltered (_("Deleted breakpoints "));
}
- annotate_breakpoints_changed ();
for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
{
{
struct bp_location *bl;
struct tracepoint *t;
+ int bp_location_downloaded = 0;
if ((b->type == bp_fast_tracepoint
? !may_insert_fast_tracepoints
target_download_tracepoint (bl);
bl->inserted = 1;
+ bp_location_downloaded = 1;
}
t = (struct tracepoint *) b;
t->number_on_target = b->number;
+ if (bp_location_downloaded)
+ observer_notify_breakpoint_modified (b);
}
do_cleanups (old_chain);
internal_error_pure_virtual_called ();
}
-static struct breakpoint_ops base_breakpoint_ops =
+/* The default 'explains_signal' method. */
+
+static enum bpstat_signal_value
+base_breakpoint_explains_signal (struct breakpoint *b)
+{
+ return BPSTAT_SIGNAL_HIDE;
+}
+
+struct breakpoint_ops base_breakpoint_ops =
{
base_breakpoint_dtor,
base_breakpoint_allocate_location,
base_breakpoint_create_sals_from_address,
base_breakpoint_create_breakpoints_sal,
base_breakpoint_decode_linespec,
+ base_breakpoint_explains_signal
};
/* Default breakpoint_ops methods. */
{
const char *fullname = symtab_to_fullname (sal2.symtab);
- if (fullname)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}
ui_out_field_int (uiout, "line", sal2.line);
create_longjmp_master_breakpoint ();
create_std_terminate_master_breakpoint ();
create_exception_master_breakpoint ();
-
- /* While we're at it, reset the skip list too. */
- skip_re_set ();
}
\f
/* Reset the thread number of this breakpoint:
"crossings of breakpoint %d."),
count, bptnum);
}
- annotate_breakpoints_changed ();
observer_notify_breakpoint_modified (b);
return;
}
bpt->disposition = disposition;
bpt->enable_count = count;
update_global_location_list (1);
- annotate_breakpoints_changed ();
-
+
observer_notify_breakpoint_modified (bpt);
}