gdb/
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 0023ba5a374a8e899ab33f83693972c0367760d2..c2ce96c9188ba5000977573e0b35ffd9a308af34 100644 (file)
@@ -261,6 +261,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);
@@ -981,7 +983,7 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
     }
   mark_breakpoint_modified (b);
 
-  breakpoints_changed ();
+  annotate_breakpoints_changed ();
   observer_notify_breakpoint_modified (b);
 }
 
@@ -1022,9 +1024,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 +1215,7 @@ breakpoint_set_commands (struct breakpoint *b,
 
   decref_counted_command_line (&b->commands);
   b->commands = alloc_counted_command_line (commands);
-  breakpoints_changed ();
+  annotate_breakpoints_changed ();
   observer_notify_breakpoint_modified (b);
 }
 
@@ -1329,7 +1332,7 @@ 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 ();
+      annotate_breakpoints_changed ();
       observer_notify_breakpoint_modified (b);
     }
 }
@@ -2790,7 +2793,7 @@ 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;
 
@@ -2849,7 +2852,7 @@ 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;
 
@@ -3730,7 +3733,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)
@@ -5175,7 +5178,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))
@@ -5934,7 +5937,7 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (loc != NULL
       && !header_of_multiple
       && (allflag
-         || (!gdbarch_has_global_breakpoints (target_gdbarch)
+         || (!gdbarch_has_global_breakpoints (target_gdbarch ())
              && (number_of_program_spaces () > 1
                  || number_of_inferiors () > 1)
              /* LOC is for existing B, it cannot be in
@@ -6023,28 +6026,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)
     {
@@ -6114,6 +6120,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)
@@ -6594,7 +6619,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);
 }
@@ -6609,7 +6634,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);
 }
@@ -6994,7 +7019,7 @@ init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
   if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
     b->pspace = sal.pspace;
 
-  breakpoints_changed ();
+  annotate_breakpoints_changed ();
 }
 
 /* set_raw_breakpoint is a low level routine for allocating and
@@ -7844,20 +7869,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);
@@ -7881,13 +7906,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)
@@ -8319,6 +8361,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);
@@ -10742,7 +10786,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;
@@ -11788,6 +11832,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
@@ -11836,7 +11881,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;
+      int is_abs;
 
       /* If exact pc given, clear bpts at that pc.
          If line given (pc == 0), clear all bpts on specified line.
@@ -11852,7 +11897,6 @@ clear_command (char *arg, int from_tty)
 
       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)
@@ -11885,8 +11929,7 @@ clear_command (char *arg, int from_tty)
                        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;
                    }
 
@@ -11936,7 +11979,7 @@ clear_command (char *arg, int from_tty)
       else
        printf_unfiltered (_("Deleted breakpoints "));
     }
-  breakpoints_changed ();
+  annotate_breakpoints_changed ();
 
   for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
     {
@@ -12055,7 +12098,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 ())
@@ -12063,31 +12106,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);
@@ -12525,7 +12573,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 ();
@@ -14314,7 +14362,7 @@ set_ignore_count (int bptnum, int count, int from_tty)
                               "crossings of breakpoint %d."),
                             count, bptnum);
        }
-      breakpoints_changed ();
+      annotate_breakpoints_changed ();
       observer_notify_breakpoint_modified (b);
       return;
     }
@@ -14579,7 +14627,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
   bpt->disposition = disposition;
   bpt->enable_count = count;
   update_global_location_list (1);
-  breakpoints_changed ();
+  annotate_breakpoints_changed ();
   
   observer_notify_breakpoint_modified (bpt);
 }
@@ -14999,35 +15047,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.  */
@@ -15044,18 +15090,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
@@ -15099,7 +15144,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;
     }
 
@@ -15124,15 +15169,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);
     }
@@ -15245,7 +15289,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);
@@ -15347,7 +15391,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;
@@ -16338,6 +16381,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\
This page took 0.04814 seconds and 4 git commands to generate.