X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fbreakpoint.c;h=026ce739a2fc7ce79fe2e8c1077223544e88738a;hb=05cba821addfe83535ad36f7487d1d2bbac48ba2;hp=cbb150f4be4388f65331b8a96fb4a980c7c0cea0;hpb=608b49672edd92191a25a2c365def9d2f4f51db7;p=external%2Fbinutils.git diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index cbb150f..026ce73 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1,6 +1,6 @@ /* 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. @@ -82,6 +82,13 @@ #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); @@ -261,6 +268,8 @@ static void disable_trace_command (char *, int); static void trace_pass_command (char *, int); +static void set_tracepoint_count (int num); + static int is_masked_watchpoint (const struct breakpoint *b); static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address); @@ -270,14 +279,9 @@ static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address); 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 @@ -981,7 +985,6 @@ set_breakpoint_condition (struct breakpoint *b, char *exp, } mark_breakpoint_modified (b); - breakpoints_changed (); observer_notify_breakpoint_modified (b); } @@ -1022,9 +1025,10 @@ condition_completer (struct cmd_list_element *cmd, char *text, char *word) char location[50]; if (single) - sprintf (location, "%d", b->number); + xsnprintf (location, sizeof (location), "%d", b->number); else - sprintf (location, "%d.%d", b->number, count); + xsnprintf (location, sizeof (location), "%d.%d", b->number, + count); if (strncmp (location, text, len) == 0) VEC_safe_push (char_ptr, result, xstrdup (location)); @@ -1212,7 +1216,6 @@ breakpoint_set_commands (struct breakpoint *b, decref_counted_command_line (&b->commands); b->commands = alloc_counted_command_line (commands); - breakpoints_changed (); observer_notify_breakpoint_modified (b); } @@ -1329,7 +1332,6 @@ do_map_commands_command (struct breakpoint *b, void *data) incref_counted_command_line (info->cmd); decref_counted_command_line (&b->commands); b->commands = info->cmd; - breakpoints_changed (); observer_notify_breakpoint_modified (b); } } @@ -1844,11 +1846,10 @@ update_watchpoint (struct watchpoint *b, int reparse) && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) { CORE_ADDR addr; - int len, type; + int type; struct bp_location *loc, **tmp; addr = value_address (v); - len = TYPE_LENGTH (value_type (v)); type = hw_write; if (b->base.type == bp_read_watchpoint) type = hw_read; @@ -1863,7 +1864,7 @@ update_watchpoint (struct watchpoint *b, int reparse) loc->pspace = frame_pspace; loc->address = addr; - loc->length = len; + loc->length = TYPE_LENGTH (value_type (v)); loc->watchpoint_type = type; } } @@ -2375,9 +2376,12 @@ static int insert_bp_location (struct bp_location *bl, struct ui_file *tmp_error_stream, int *disabled_breaks, - int *hw_breakpoint_error) + int *hw_breakpoint_error, + int *hw_bp_error_explained_already) { int val = 0; + char *hw_bp_err_string = NULL; + struct gdb_exception e; if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update)) return 0; @@ -2474,8 +2478,15 @@ insert_bp_location (struct bp_location *bl, || !(section_is_overlay (bl->section))) { /* No overlay handling: just set the breakpoint. */ - - val = bl->owner->ops->insert_location (bl); + TRY_CATCH (e, RETURN_MASK_ALL) + { + val = bl->owner->ops->insert_location (bl); + } + if (e.reason < 0) + { + val = 1; + hw_bp_err_string = (char *) e.message; + } } else { @@ -2509,7 +2520,15 @@ insert_bp_location (struct bp_location *bl, if (section_is_mapped (bl->section)) { /* Yes. This overlay section is mapped into memory. */ - val = bl->owner->ops->insert_location (bl); + TRY_CATCH (e, RETURN_MASK_ALL) + { + val = bl->owner->ops->insert_location (bl); + } + if (e.reason < 0) + { + val = 1; + hw_bp_err_string = (char *) e.message; + } } else { @@ -2545,11 +2564,13 @@ insert_bp_location (struct bp_location *bl, { if (bl->loc_type == bp_loc_hardware_breakpoint) { - *hw_breakpoint_error = 1; - fprintf_unfiltered (tmp_error_stream, - "Cannot insert hardware " - "breakpoint %d.\n", - bl->owner->number); + *hw_breakpoint_error = 1; + *hw_bp_error_explained_already = hw_bp_err_string != NULL; + fprintf_unfiltered (tmp_error_stream, + "Cannot insert hardware breakpoint %d%s", + bl->owner->number, hw_bp_err_string ? ":" : ".\n"); + if (hw_bp_err_string) + fprintf_unfiltered (tmp_error_stream, "%s.\n", hw_bp_err_string); } else { @@ -2741,6 +2762,7 @@ update_inserted_breakpoint_locations (void) int val = 0; int disabled_breaks = 0; int hw_breakpoint_error = 0; + int hw_bp_details_reported = 0; struct ui_file *tmp_error_stream = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream); @@ -2770,12 +2792,12 @@ update_inserted_breakpoint_locations (void) to select an inferior to insert breakpoint to. In fact, even if we aren't attached to any process yet, we should still insert breakpoints. */ - if (!gdbarch_has_global_breakpoints (target_gdbarch) + if (!gdbarch_has_global_breakpoints (target_gdbarch ()) && ptid_equal (inferior_ptid, null_ptid)) continue; val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks, - &hw_breakpoint_error); + &hw_breakpoint_error, &hw_bp_details_reported); if (val) error_flag = val; } @@ -2800,6 +2822,7 @@ insert_breakpoint_locations (void) int val = 0; int disabled_breaks = 0; int hw_breakpoint_error = 0; + int hw_bp_error_explained_already = 0; struct ui_file *tmp_error_stream = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream); @@ -2828,12 +2851,12 @@ insert_breakpoint_locations (void) to select an inferior to insert breakpoint to. In fact, even if we aren't attached to any process yet, we should still insert breakpoints. */ - if (!gdbarch_has_global_breakpoints (target_gdbarch) + if (!gdbarch_has_global_breakpoints (target_gdbarch ()) && ptid_equal (inferior_ptid, null_ptid)) continue; val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks, - &hw_breakpoint_error); + &hw_breakpoint_error, &hw_bp_error_explained_already); if (val) error_flag = val; } @@ -2878,7 +2901,7 @@ insert_breakpoint_locations (void) { /* If a hardware breakpoint or watchpoint was inserted, add a message about possibly exhausted resources. */ - if (hw_breakpoint_error) + if (hw_breakpoint_error && !hw_bp_error_explained_already) { fprintf_unfiltered (tmp_error_stream, "Could not insert hardware breakpoints:\n\ @@ -2943,7 +2966,7 @@ reattach_breakpoints (int pid) struct bp_location *bl, **blp_tmp; int val; struct ui_file *tmp_error_stream; - int dummy1 = 0, dummy2 = 0; + int dummy1 = 0, dummy2 = 0, dummy3 = 0; struct inferior *inf; struct thread_info *tp; @@ -2967,7 +2990,7 @@ reattach_breakpoints (int pid) if (bl->inserted) { bl->inserted = 0; - val = insert_bp_location (bl, tmp_error_stream, &dummy1, &dummy2); + val = insert_bp_location (bl, tmp_error_stream, &dummy1, &dummy2, &dummy3); if (val != 0) { do_cleanups (old_chain); @@ -3500,18 +3523,18 @@ update_breakpoints_after_exec (void) } int -detach_breakpoints (int pid) +detach_breakpoints (ptid_t ptid) { struct bp_location *bl, **blp_tmp; int val = 0; struct cleanup *old_chain = save_inferior_ptid (); struct inferior *inf = current_inferior (); - if (pid == PIDGET (inferior_ptid)) + if (PIDGET (ptid) == PIDGET (inferior_ptid)) error (_("Cannot detach breakpoints of inferior_ptid")); /* Set inferior_ptid; remove_breakpoint_1 uses this global. */ - inferior_ptid = pid_to_ptid (pid); + inferior_ptid = ptid; ALL_BP_LOCATIONS (bl, blp_tmp) { if (bl->pspace != inf->pspace) @@ -3709,7 +3732,7 @@ breakpoint_init_inferior (enum inf_context context) /* If breakpoint locations are shared across processes, then there's nothing to do. */ - if (gdbarch_has_global_breakpoints (target_gdbarch)) + if (gdbarch_has_global_breakpoints (target_gdbarch ())) return; ALL_BP_LOCATIONS (bl, blp_tmp) @@ -4121,6 +4144,29 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint) 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 @@ -5088,7 +5134,6 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) 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); @@ -5154,7 +5199,7 @@ bpstat_stop_status (struct address_space *aspace, if (b->type == bp_hardware_watchpoint && bl != b->loc) break; - if (bl->shlib_disabled) + if (!bl->enabled || bl->shlib_disabled) continue; if (!bpstat_check_location (bl, aspace, bp_addr, ws)) @@ -5649,7 +5694,7 @@ print_breakpoint_location (struct breakpoint *b, if (b->display_canonical) ui_out_field_string (uiout, "what", b->addr_string); - else if (loc && loc->source_file) + else if (loc && loc->symtab) { struct symbol *sym = find_pc_sect_function (loc->address, loc->section); @@ -5662,17 +5707,13 @@ print_breakpoint_location (struct breakpoint *b, ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what")); ui_out_text (uiout, "at "); } - ui_out_field_string (uiout, "file", loc->source_file); + ui_out_field_string (uiout, "file", + symtab_to_filename_for_display (loc->symtab)); ui_out_text (uiout, ":"); - + if (ui_out_is_mi_like_p (uiout)) - { - struct symtab_and_line sal = find_pc_line (loc->address, 0); - char *fullname = symtab_to_fullname (sal.symtab); - - if (fullname) - ui_out_field_string (uiout, "fullname", fullname); - } + ui_out_field_string (uiout, "fullname", + symtab_to_fullname (loc->symtab)); ui_out_field_int (uiout, "line", loc->line_number); } @@ -5757,6 +5798,51 @@ bptype_string (enum bptype type) 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 @@ -5908,35 +5994,30 @@ print_one_breakpoint_location (struct breakpoint *b, } - /* 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) @@ -6002,28 +6083,31 @@ print_one_breakpoint_location (struct breakpoint *b, ui_out_text (uiout, "\n"); } - if (!part_of_multiple && b->hit_count) + if (!part_of_multiple) { - /* FIXME should make an annotation for this. */ - if (is_catchpoint (b)) - ui_out_text (uiout, "\tcatchpoint"); - else if (is_tracepoint (b)) - ui_out_text (uiout, "\ttracepoint"); - else - ui_out_text (uiout, "\tbreakpoint"); - ui_out_text (uiout, " already hit "); - ui_out_field_int (uiout, "times", b->hit_count); - if (b->hit_count == 1) - ui_out_text (uiout, " time\n"); + if (b->hit_count) + { + /* FIXME should make an annotation for this. */ + if (is_catchpoint (b)) + ui_out_text (uiout, "\tcatchpoint"); + else if (is_tracepoint (b)) + ui_out_text (uiout, "\ttracepoint"); + else + ui_out_text (uiout, "\tbreakpoint"); + ui_out_text (uiout, " already hit "); + ui_out_field_int (uiout, "times", b->hit_count); + if (b->hit_count == 1) + ui_out_text (uiout, " time\n"); + else + ui_out_text (uiout, " times\n"); + } else - ui_out_text (uiout, " times\n"); + { + /* Output the count also if it is zero, but only if this is mi. */ + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_int (uiout, "times", b->hit_count); + } } - - /* Output the count also if it is zero, but only if this is mi. - FIXME: Should have a better test for this. */ - if (ui_out_is_mi_like_p (uiout)) - if (!part_of_multiple && b->hit_count == 0) - ui_out_field_int (uiout, "times", b->hit_count); if (!part_of_multiple && b->ignore_count) { @@ -6061,15 +6145,6 @@ print_one_breakpoint_location (struct breakpoint *b, 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) @@ -6093,6 +6168,25 @@ print_one_breakpoint_location (struct breakpoint *b, 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) @@ -6573,7 +6667,7 @@ static int breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1, struct address_space *aspace2, CORE_ADDR addr2) { - return ((gdbarch_has_global_breakpoints (target_gdbarch) + return ((gdbarch_has_global_breakpoints (target_gdbarch ()) || aspace1 == aspace2) && addr1 == addr2); } @@ -6588,7 +6682,7 @@ breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1, int len1, struct address_space *aspace2, CORE_ADDR addr2) { - return ((gdbarch_has_global_breakpoints (target_gdbarch) + return ((gdbarch_has_global_breakpoints (target_gdbarch ()) || aspace1 == aspace2) && addr2 >= addr1 && addr2 < addr1 + len1); } @@ -6972,8 +7066,6 @@ init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch, program space. */ if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint) b->pspace = sal.pspace; - - breakpoints_changed (); } /* set_raw_breakpoint is a low level routine for allocating and @@ -7486,6 +7578,9 @@ print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc) 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 @@ -7599,6 +7694,9 @@ print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc) 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 @@ -7797,6 +7895,10 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs) } 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 @@ -7823,20 +7925,20 @@ print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp) static struct breakpoint_ops catch_solib_breakpoint_ops; -/* A helper function that does all the work for "catch load" and - "catch unload". */ +/* Shared helper function (MI and CLI) for creating and installing + a shared object event catchpoint. If IS_LOAD is non-zero then + the events to be caught are load events, otherwise they are + unload events. If IS_TEMP is non-zero the catchpoint is a + temporary one. If ENABLED is non-zero the catchpoint is + created in an enabled state. */ -static void -catch_load_or_unload (char *arg, int from_tty, int is_load, - struct cmd_list_element *command) +void +add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled) { struct solib_catchpoint *c; struct gdbarch *gdbarch = get_current_arch (); - int tempflag; struct cleanup *cleanup; - tempflag = get_cmd_context (command) == CATCH_TEMPORARY; - if (!arg) arg = ""; arg = skip_spaces (arg); @@ -7860,13 +7962,30 @@ catch_load_or_unload (char *arg, int from_tty, int is_load, } c->is_load = is_load; - init_catchpoint (&c->base, gdbarch, tempflag, NULL, + init_catchpoint (&c->base, gdbarch, is_temp, NULL, &catch_solib_breakpoint_ops); + c->base.enable_state = enabled ? bp_enabled : bp_disabled; + discard_cleanups (cleanup); install_breakpoint (0, &c->base, 1); } +/* A helper function that does all the work for "catch load" and + "catch unload". */ + +static void +catch_load_or_unload (char *arg, int from_tty, int is_load, + struct cmd_list_element *command) +{ + int tempflag; + const int enabled = 1; + + tempflag = get_cmd_context (command) == CATCH_TEMPORARY; + + add_solib_catchpoint (arg, is_load, tempflag, enabled); +} + static void catch_load_command_1 (char *arg, int from_tty, struct cmd_list_element *command) @@ -7881,8 +8000,6 @@ catch_unload_command_1 (char *arg, int from_tty, 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 @@ -8191,6 +8308,9 @@ print_one_catch_syscall (struct breakpoint *b, else ui_out_field_string (uiout, "what", ""); 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 @@ -8276,7 +8396,7 @@ syscall_catchpoint_p (struct breakpoint *b) 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, @@ -8298,6 +8418,8 @@ install_breakpoint (int internal, struct breakpoint *b, int update_gll) { add_to_breakpoint_chain (b); set_breakpoint_number (internal, b); + if (is_tracepoint (b)) + set_tracepoint_count (breakpoint_count); if (!internal) mention (b); observer_notify_breakpoint_created (b); @@ -8426,6 +8548,9 @@ print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc) 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 @@ -8587,9 +8712,9 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal, { struct breakpoint *b; - /* If FRAME_ID is valid, it should be a real frame, not an inlined - one. */ - gdb_assert (!frame_id_inlined_p (frame_id)); + /* If FRAME_ID is valid, it should be a real frame, not an inlined or + tail-called one. */ + gdb_assert (!frame_id_artificial_p (frame_id)); b = set_raw_breakpoint (gdbarch, sal, type, &momentary_breakpoint_ops); b->enable_state = bp_enabled; @@ -8628,11 +8753,8 @@ momentary_breakpoint_from_master (struct breakpoint *orig, copy->loc->section = orig->loc->section; copy->loc->pspace = orig->loc->pspace; copy->loc->probe = orig->loc->probe; - - if (orig->loc->source_file != NULL) - copy->loc->source_file = xstrdup (orig->loc->source_file); - copy->loc->line_number = orig->loc->line_number; + copy->loc->symtab = orig->loc->symtab; copy->frame_id = orig->frame_id; copy->thread = orig->thread; copy->pspace = orig->pspace; @@ -8717,10 +8839,8 @@ add_location_to_breakpoint (struct breakpoint *b, gdb_assert (loc->pspace != NULL); loc->section = sal->section; loc->gdbarch = loc_gdbarch; - - if (sal->symtab != NULL) - loc->source_file = xstrdup (sal->symtab->filename); loc->line_number = sal->line; + loc->symtab = sal->symtab; set_breakpoint_location_function (loc, sal->explicit_pc || sal->explicit_line); @@ -8823,30 +8943,30 @@ update_dprintf_command_list (struct breakpoint *b) 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 @@ -9115,8 +9235,6 @@ static void parse_breakpoint_sals (char **address, struct linespec_result *canonical) { - char *addr_start = *address; - /* If no arg given, or if first arg is 'if ', use the default breakpoint. */ if ((*address) == NULL @@ -9128,21 +9246,27 @@ parse_breakpoint_sals (char **address, { struct linespec_sals lsal; struct symtab_and_line sal; + CORE_ADDR pc; init_sal (&sal); /* Initialize to zeroes. */ lsal.sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); /* Set sal's pspace, pc, symtab, and line to the values - corresponding to the last call to print_frame_info. */ + corresponding to the last call to print_frame_info. + Be sure to reinitialize LINE with NOTCURRENT == 0 + as the breakpoint line number is inappropriate otherwise. + find_pc_line would adjust PC, re-set it back. */ get_last_displayed_sal (&sal); - sal.section = find_pc_overlay (sal.pc); + pc = sal.pc; + sal = find_pc_line (pc, 0); /* "break" without arguments is equivalent to "break *PC" where PC is the last displayed codepoint's address. So make sure to set sal.explicit_pc to prevent GDB from trying to expand the list of sals to include all other instances with the same symtab and line. */ + sal.pc = pc; sal.explicit_pc = 1; lsal.sals.sals[0] = sal; @@ -9557,7 +9681,18 @@ create_breakpoint (struct gdbarch *gdbarch, init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops); b->addr_string = copy_arg; - b->cond_string = NULL; + if (parse_condition_and_thread) + b->cond_string = NULL; + else + { + /* Create a private copy of condition string. */ + if (cond_string) + { + cond_string = xstrdup (cond_string); + make_cleanup (xfree, cond_string); + } + b->cond_string = cond_string; + } b->extra_string = NULL; b->ignore_count = ignore_count; b->disposition = tempflag ? disp_del : disp_donttouch; @@ -9636,7 +9771,7 @@ resolve_sal_pc (struct symtab_and_line *sal) { if (!find_line_pc (sal->symtab, sal->line, &pc)) error (_("No line %d in file \"%s\"."), - sal->line, sal->symtab->filename); + sal->line, symtab_to_filename_for_display (sal->symtab)); sal->pc = pc; /* If this SAL corresponds to a breakpoint inserted using a line @@ -9779,14 +9914,12 @@ stopat_command (char *arg, int from_tty) 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 (), @@ -10151,7 +10284,6 @@ watchpoint_exp_is_const (const struct expression *exp) case BINOP_RANGE: case TERNOP_COND: case TERNOP_SLICE: - case TERNOP_SLICE_COUNT: case OP_LONG: case OP_DOUBLE: @@ -10159,7 +10291,6 @@ watchpoint_exp_is_const (const struct expression *exp) case OP_LAST: case OP_COMPLEX: case OP_STRING: - case OP_BITSTRING: case OP_ARRAY: case OP_TYPE: case OP_TYPEOF: @@ -10708,7 +10839,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty, volatile struct gdb_exception e; struct breakpoint *b, *scope_breakpoint = NULL; struct expression *exp; - struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL; + const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL; struct value *val, *mark, *result; struct frame_info *frame; char *exp_start = NULL; @@ -11463,9 +11594,17 @@ print_one_exception_catchpoint (struct breakpoint *b, 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 @@ -11732,7 +11871,7 @@ compare_breakpoints (const void *a, const void *b) the number 0. */ if (ua < ub) return -1; - return ub > ub ? 1 : 0; + return ua > ub ? 1 : 0; } /* Delete breakpoints by address or line. */ @@ -11754,6 +11893,7 @@ clear_command (char *arg, int from_tty) sals = decode_line_with_current_source (arg, (DECODE_LINE_FUNFIRSTLINE | DECODE_LINE_LIST_MODE)); + make_cleanup (xfree, sals.sals); default_match = 0; } else @@ -11802,7 +11942,7 @@ clear_command (char *arg, int from_tty) make_cleanup (VEC_cleanup (breakpoint_p), &found); for (i = 0; i < sals.nelts; i++) { - int is_abs, sal_name_len; + const char *sal_fullname; /* If exact pc given, clear bpts at that pc. If line given (pc == 0), clear all bpts on specified line. @@ -11817,8 +11957,8 @@ clear_command (char *arg, int from_tty) 1 0 */ 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); + sal_fullname = (sal.symtab == NULL + ? NULL : symtab_to_fullname (sal.symtab)); /* Find all matching breakpoints and add them to 'found'. */ ALL_BREAKPOINTS (b) @@ -11841,20 +11981,13 @@ clear_command (char *arg, int from_tty) int line_match = 0; if ((default_match || sal.explicit_line) - && loc->source_file != NULL - && sal.symtab != NULL + && loc->symtab != NULL + && sal_fullname != NULL && sal.pspace == loc->pspace - && loc->line_number == sal.line) - { - if (filename_cmp (loc->source_file, - sal.symtab->filename) == 0) - line_match = 1; - else if (!IS_ABSOLUTE_PATH (sal.symtab->filename) - && compare_filenames_for_search (loc->source_file, - sal.symtab->filename, - sal_name_len)) - line_match = 1; - } + && loc->line_number == sal.line + && filename_cmp (symtab_to_fullname (loc->symtab), + sal_fullname) == 0) + line_match = 1; if (pc_match || line_match) { @@ -11902,7 +12035,6 @@ clear_command (char *arg, int from_tty) else printf_unfiltered (_("Deleted breakpoints ")); } - breakpoints_changed (); for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++) { @@ -12021,7 +12153,7 @@ bp_location_target_extensions_update (void) static void download_tracepoint_locations (void) { - struct bp_location *bl, **blp_tmp; + struct breakpoint *b; struct cleanup *old_chain; if (!target_can_download_tracepoint ()) @@ -12029,31 +12161,36 @@ download_tracepoint_locations (void) old_chain = save_current_space_and_thread (); - ALL_BP_LOCATIONS (bl, blp_tmp) + ALL_TRACEPOINTS (b) { + struct bp_location *bl; struct tracepoint *t; + int bp_location_downloaded = 0; - if (!is_tracepoint (bl->owner)) - continue; - - if ((bl->owner->type == bp_fast_tracepoint + if ((b->type == bp_fast_tracepoint ? !may_insert_fast_tracepoints : !may_insert_tracepoints)) continue; - /* In tracepoint, locations are _never_ duplicated, so - should_be_inserted is equivalent to - unduplicated_should_be_inserted. */ - if (!should_be_inserted (bl) || bl->inserted) - continue; + for (bl = b->loc; bl; bl = bl->next) + { + /* In tracepoint, locations are _never_ duplicated, so + should_be_inserted is equivalent to + unduplicated_should_be_inserted. */ + if (!should_be_inserted (bl) || bl->inserted) + continue; - switch_to_program_space_and_thread (bl->pspace); + switch_to_program_space_and_thread (bl->pspace); - target_download_tracepoint (bl); + target_download_tracepoint (bl); - bl->inserted = 1; - t = (struct tracepoint *) bl->owner; - t->number_on_target = bl->owner->number; + 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); @@ -12428,7 +12565,7 @@ update_global_location_list (int should_insert) struct bp_location **loc_first_p; b = loc->owner; - if (!should_be_inserted (loc) + if (!unduplicated_should_be_inserted (loc) || !breakpoint_address_is_meaningful (b) /* Don't detect duplicate for tracepoint locations because they are never duplicated. See the comments in field `duplicate' of @@ -12491,7 +12628,7 @@ update_global_location_list (int should_insert) if (breakpoints_always_inserted_mode () && (have_live_inferiors () - || (gdbarch_has_global_breakpoints (target_gdbarch)))) + || (gdbarch_has_global_breakpoints (target_gdbarch ())))) { if (should_insert) insert_breakpoint_locations (); @@ -12580,19 +12717,20 @@ say_where (struct breakpoint *b) } else { - if (opts.addressprint || b->loc->source_file == NULL) + if (opts.addressprint || b->loc->symtab == NULL) { printf_filtered (" at "); fputs_filtered (paddress (b->loc->gdbarch, b->loc->address), gdb_stdout); } - if (b->loc->source_file) + if (b->loc->symtab != NULL) { /* If there is a single location, we can print the location more nicely. */ if (b->loc->next == NULL) printf_filtered (": file %s, line %d.", - b->loc->source_file, b->loc->line_number); + symtab_to_filename_for_display (b->loc->symtab), + b->loc->line_number); else /* This is not ideal, but each location may have a different file name, and this at least reflects the @@ -12620,7 +12758,6 @@ bp_location_dtor (struct bp_location *self) if (self->cond_bytecode) free_agent_expr (self->cond_bytecode); xfree (self->function_name); - xfree (self->source_file); } static const struct bp_location_ops bp_location_ops = @@ -12764,7 +12901,15 @@ base_breakpoint_decode_linespec (struct breakpoint *b, char **s, 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, @@ -12783,6 +12928,7 @@ static struct breakpoint_ops base_breakpoint_ops = base_breakpoint_create_sals_from_address, base_breakpoint_create_breakpoints_sal, base_breakpoint_decode_linespec, + base_breakpoint_explains_signal }; /* Default breakpoint_ops methods. */ @@ -13783,31 +13929,26 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) SYMBOL_PRINT_NAME (sym)); ui_out_text (uiout, " at "); } - ui_out_field_string (uiout, "file", sal2.symtab->filename); + ui_out_field_string (uiout, "file", + symtab_to_filename_for_display (sal2.symtab)); ui_out_text (uiout, ":"); if (ui_out_is_mi_like_p (uiout)) { - char *fullname = symtab_to_fullname (sal2.symtab); + 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); ui_out_text (uiout, "\n"); b->loc->line_number = sal2.line; - - xfree (b->loc->source_file); - if (sym) - b->loc->source_file = xstrdup (sal2.symtab->filename); - else - b->loc->source_file = NULL; + b->loc->symtab = sym != NULL ? sal2.symtab : NULL; xfree (b->addr_string); b->addr_string = xstrprintf ("%s:%d", - sal2.symtab->filename, + symtab_to_filename_for_display (sal2.symtab), b->loc->line_number); /* Might be nice to check if function changed, and warn if @@ -14217,9 +14358,6 @@ breakpoint_re_set (void) 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 (); } /* Reset the thread number of this breakpoint: @@ -14280,7 +14418,6 @@ set_ignore_count (int bptnum, int count, int from_tty) "crossings of breakpoint %d."), count, bptnum); } - breakpoints_changed (); observer_notify_breakpoint_modified (b); return; } @@ -14545,8 +14682,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition, bpt->disposition = disposition; bpt->enable_count = count; update_global_location_list (1); - breakpoints_changed (); - + observer_notify_breakpoint_modified (bpt); } @@ -14684,7 +14820,8 @@ show_breakpoint_cmd (char *args, int from_tty) GDB itself. */ static void -invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len, +invalidate_bp_value_on_memory_change (struct inferior *inferior, + CORE_ADDR addr, ssize_t len, const bfd_byte *data) { struct breakpoint *bp; @@ -14937,7 +15074,7 @@ catch_syscall_completer (struct cmd_list_element *cmd, { const char **list = get_syscall_names (); VEC (char_ptr) *retlist - = (list == NULL) ? NULL : complete_on_enum (list, text, word); + = (list == NULL) ? NULL : complete_on_enum (list, word, word); xfree (list); return retlist; @@ -14964,35 +15101,33 @@ trace_command (char *arg, int from_tty) else ops = &tracepoint_breakpoint_ops; - if (create_breakpoint (get_current_arch (), - arg, - NULL, 0, NULL, 1 /* parse arg */, - 0 /* tempflag */, - bp_tracepoint /* type_wanted */, - 0 /* Ignore count */, - pending_break_support, - ops, - from_tty, - 1 /* enabled */, - 0 /* internal */, 0)) - set_tracepoint_count (breakpoint_count); + create_breakpoint (get_current_arch (), + arg, + NULL, 0, NULL, 1 /* parse arg */, + 0 /* tempflag */, + bp_tracepoint /* type_wanted */, + 0 /* Ignore count */, + pending_break_support, + ops, + from_tty, + 1 /* enabled */, + 0 /* internal */, 0); } static void ftrace_command (char *arg, int from_tty) { - if (create_breakpoint (get_current_arch (), - arg, - NULL, 0, NULL, 1 /* parse arg */, - 0 /* tempflag */, - bp_fast_tracepoint /* type_wanted */, - 0 /* Ignore count */, - pending_break_support, - &tracepoint_breakpoint_ops, - from_tty, - 1 /* enabled */, - 0 /* internal */, 0)) - set_tracepoint_count (breakpoint_count); + create_breakpoint (get_current_arch (), + arg, + NULL, 0, NULL, 1 /* parse arg */, + 0 /* tempflag */, + bp_fast_tracepoint /* type_wanted */, + 0 /* Ignore count */, + pending_break_support, + &tracepoint_breakpoint_ops, + from_tty, + 1 /* enabled */, + 0 /* internal */, 0); } /* strace command implementation. Creates a static tracepoint. */ @@ -15009,18 +15144,17 @@ strace_command (char *arg, int from_tty) else ops = &tracepoint_breakpoint_ops; - if (create_breakpoint (get_current_arch (), - arg, - NULL, 0, NULL, 1 /* parse arg */, - 0 /* tempflag */, - bp_static_tracepoint /* type_wanted */, - 0 /* Ignore count */, - pending_break_support, - ops, - from_tty, - 1 /* enabled */, - 0 /* internal */, 0)) - set_tracepoint_count (breakpoint_count); + create_breakpoint (get_current_arch (), + arg, + NULL, 0, NULL, 1 /* parse arg */, + 0 /* tempflag */, + bp_static_tracepoint /* type_wanted */, + 0 /* Ignore count */, + pending_break_support, + ops, + from_tty, + 1 /* enabled */, + 0 /* internal */, 0); } /* Set up a fake reader function that gets command lines from a linked @@ -15064,7 +15198,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) warning (_("Uploaded tracepoint %d has no " "source location, using raw address"), utp->number); - sprintf (small_buf, "*%s", hex_string (utp->addr)); + xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (utp->addr)); addr_str = small_buf; } @@ -15089,15 +15223,14 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) CREATE_BREAKPOINT_FLAGS_INSERTED)) return NULL; - set_tracepoint_count (breakpoint_count); - /* Get the tracepoint we just created. */ tp = get_tracepoint (tracepoint_count); gdb_assert (tp != NULL); if (utp->pass > 0) { - sprintf (small_buf, "%d %d", utp->pass, tp->base.number); + xsnprintf (small_buf, sizeof (small_buf), "%d %d", utp->pass, + tp->base.number); trace_pass_command (small_buf, 0); } @@ -15210,7 +15343,7 @@ static void trace_pass_set_count (struct tracepoint *tp, int count, int from_tty) { tp->pass_count = count; - observer_notify_tracepoint_modified (tp->base.number); + observer_notify_breakpoint_modified (&tp->base); if (from_tty) printf_filtered (_("Setting tracepoint %d's passcount to %d\n"), tp->base.number, count); @@ -15312,7 +15445,6 @@ get_tracepoint_by_number (char **arg, struct get_number_or_range_state *state, int optional_p) { - extern int tracepoint_count; struct breakpoint *t; int tpnum; char *instring = arg == NULL ? NULL : *arg; @@ -15649,6 +15781,18 @@ pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc, return 0; } +/* Remove any references to OBJFILE which is going to be freed. */ + +void +breakpoint_free_objfile (struct objfile *objfile) +{ + struct bp_location **locp, *loc; + + ALL_BP_LOCATIONS (loc, locp) + if (loc->symtab != NULL && loc->symtab->objfile == objfile) + loc->symtab = NULL; +} + void initialize_breakpoint_ops (void) { @@ -15850,6 +15994,10 @@ initialize_breakpoint_ops (void) ops->print_recreate = bkpt_print_recreate; } +/* Chain containing all defined "enable breakpoint" subcommands. */ + +static struct cmd_list_element *enablebreaklist = NULL; + void _initialize_breakpoint (void) { @@ -15865,7 +16013,8 @@ _initialize_breakpoint (void) = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes); catch_syscall_inferior_data - = register_inferior_data_with_cleanup (catch_syscall_inferior_data_cleanup); + = 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 @@ -16298,6 +16447,7 @@ Delete specified tracepoints.\n\ Arguments are tracepoint numbers, separated by spaces.\n\ No argument means delete all tracepoints."), &deletelist); + add_alias_cmd ("tr", "tracepoints", class_trace, 1, &deletelist); c = add_cmd ("tracepoints", class_trace, disable_trace_command, _("\ Disable specified tracepoints.\n\