update to 2.23.1
[platform/upstream/binutils.git] / gdb / breakpoint.c
index 3f372de..a144a7e 100644 (file)
@@ -51,7 +51,6 @@
 #include "solib.h"
 #include "solist.h"
 #include "observer.h"
-#include "exceptions.h"
 #include "memattr.h"
 #include "ada-lang.h"
 #include "top.h"
@@ -258,12 +257,17 @@ enum ugll_insert_mode
      the inferior.  */
   UGLL_DONT_INSERT,
 
-  /* May insert breakpoints if breakpoints_always_inserted_mode is
-     true.  */
+  /* May insert breakpoints iff breakpoints_should_be_inserted_now
+     claims breakpoints should be inserted now.  */
   UGLL_MAY_INSERT,
 
-  /* Insert locations now, even if breakpoints_always_inserted_mode is
-     false.  */
+  /* Insert locations now, irrespective of
+     breakpoints_should_be_inserted_now.  E.g., say all threads are
+     stopped right now, and the user did "continue".  We need to
+     insert breakpoints _before_ resuming the target, but
+     UGLL_MAY_INSERT wouldn't insert them, because
+     breakpoints_should_be_inserted_now returns false at that point,
+     as no thread is running yet.  */
   UGLL_INSERT
 };
 
@@ -451,34 +455,48 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* If on, gdb will keep breakpoints inserted even as inferior is
-   stopped, and immediately insert any new breakpoints.  If off, gdb
-   will insert breakpoints into inferior only when resuming it, and
-   will remove breakpoints upon stop.  If auto, GDB will behave as ON
-   if in non-stop mode, and as OFF if all-stop mode.*/
-
-static enum auto_boolean always_inserted_mode = AUTO_BOOLEAN_AUTO;
+/* If on, GDB keeps breakpoints inserted even if the inferior is
+   stopped, and immediately inserts any new breakpoints as soon as
+   they're created.  If off (default), GDB keeps breakpoints off of
+   the target as long as possible.  That is, it delays inserting
+   breakpoints until the next resume, and removes them again when the
+   target fully stops.  This is a bit safer in case GDB crashes while
+   processing user input.  */
+static int always_inserted_mode = 0;
 
 static void
 show_always_inserted_mode (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  if (always_inserted_mode == AUTO_BOOLEAN_AUTO)
-    fprintf_filtered (file,
-                     _("Always inserted breakpoint "
-                       "mode is %s (currently %s).\n"),
-                     value,
-                     breakpoints_always_inserted_mode () ? "on" : "off");
-  else
-    fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
-                     value);
+  fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
+                   value);
 }
 
+/* See breakpoint.h.  */
+
 int
-breakpoints_always_inserted_mode (void)
+breakpoints_should_be_inserted_now (void)
 {
-  return (always_inserted_mode == AUTO_BOOLEAN_TRUE
-         || (always_inserted_mode == AUTO_BOOLEAN_AUTO && non_stop));
+  if (gdbarch_has_global_breakpoints (target_gdbarch ()))
+    {
+      /* If breakpoints are global, they should be inserted even if no
+        thread under gdb's control is running, or even if there are
+        no threads under GDB's control yet.  */
+      return 1;
+    }
+  else if (target_has_execution)
+    {
+      if (always_inserted_mode)
+       {
+         /* The user wants breakpoints inserted even if all threads
+            are stopped.  */
+         return 1;
+       }
+
+      if (threads_are_executing ())
+       return 1;
+    }
+  return 0;
 }
 
 static const char condition_evaluation_both[] = "host or target";
@@ -1525,8 +1543,8 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
   else
     {
       const unsigned char *bp;
-      CORE_ADDR placed_address = target_info->placed_address;
-      int placed_size = target_info->placed_size;
+      CORE_ADDR addr = target_info->reqstd_address;
+      int placed_size;
 
       /* Update the shadow with what we want to write to memory.  */
       memcpy (target_info->shadow_contents + bptoffset,
@@ -1534,7 +1552,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 
       /* Determine appropriate breakpoint contents and size for this
         address.  */
-      bp = gdbarch_breakpoint_from_pc (gdbarch, &placed_address, &placed_size);
+      bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &placed_size);
 
       /* Update the final write buffer with this inserted
         breakpoint's INSN.  */
@@ -2179,7 +2197,16 @@ should_be_inserted (struct bp_location *bl)
        || bl->loc_type == bp_loc_hardware_breakpoint)
       && stepping_past_instruction_at (bl->pspace->aspace,
                                       bl->address))
-    return 0;
+    {
+      if (debug_infrun)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: skipping breakpoint: "
+                             "stepping past insn at: %s\n",
+                             paddress (bl->gdbarch, bl->address));
+       }
+      return 0;
+    }
 
   return 1;
 }
@@ -2573,7 +2600,7 @@ insert_bp_location (struct bp_location *bl,
      we have a breakpoint inserted at that address and thus
      read the breakpoint instead of returning the data saved in
      the breakpoint location's shadow contents.  */
-  bl->target_info.placed_address = bl->address;
+  bl->target_info.reqstd_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
   bl->target_info.length = bl->length;
 
@@ -2614,7 +2641,7 @@ insert_bp_location (struct bp_location *bl,
             program, but it's not going to work anyway with current
             gdb.  */
          struct mem_region *mr 
-           = lookup_mem_region (bl->target_info.placed_address);
+           = lookup_mem_region (bl->target_info.reqstd_address);
          
          if (mr)
            {
@@ -2643,10 +2670,16 @@ insert_bp_location (struct bp_location *bl,
                    }
                }
              else if (bl->loc_type == bp_loc_software_breakpoint
-                      && mr->attrib.mode != MEM_RW)        
-               warning (_("cannot set software breakpoint "
-                          "at readonly address %s"),
-                        paddress (bl->gdbarch, bl->address));
+                      && mr->attrib.mode != MEM_RW)
+               {
+                 fprintf_unfiltered (tmp_error_stream,
+                                     _("Cannot insert breakpoint %d.\n"
+                                       "Cannot set software breakpoint "
+                                       "at read-only address %s\n"),
+                                     bl->owner->number,
+                                     paddress (bl->gdbarch, bl->address));
+                 return 1;
+               }
            }
        }
         
@@ -2688,7 +2721,7 @@ insert_bp_location (struct bp_location *bl,
                                                             bl->section);
                  /* Set a software (trap) breakpoint at the LMA.  */
                  bl->overlay_target_info = bl->target_info;
-                 bl->overlay_target_info.placed_address = addr;
+                 bl->overlay_target_info.reqstd_address = addr;
 
                  /* No overlay handling: just set the breakpoint.  */
                  TRY_CATCH (e, RETURN_MASK_ALL)
@@ -3802,11 +3835,6 @@ update_breakpoints_after_exec (void)
        continue;
       }
   }
-  /* FIXME what about longjmp breakpoints?  Re-create them here?  */
-  create_overlay_event_breakpoint ();
-  create_longjmp_master_breakpoint ();
-  create_std_terminate_master_breakpoint ();
-  create_exception_master_breakpoint ();
 }
 
 int
@@ -12930,10 +12958,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
                        "a permanent breakpoint"));
     }
 
-  if (insert_mode == UGLL_INSERT
-      || (breakpoints_always_inserted_mode ()
-         && (have_live_inferiors ()
-             || (gdbarch_has_global_breakpoints (target_gdbarch ())))))
+  if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ())
     {
       if (insert_mode != UGLL_DONT_INSERT)
        insert_breakpoint_locations ();
@@ -13275,6 +13300,7 @@ bp_target_info_copy_insertion_state (struct bp_target_info *dest,
 {
   dest->shadow_len = src->shadow_len;
   memcpy (dest->shadow_contents, src->shadow_contents, src->shadow_len);
+  dest->placed_address = src->placed_address;
   dest->placed_size = src->placed_size;
 }
 
@@ -13293,7 +13319,7 @@ bkpt_insert_location (struct bp_location *bl)
       /* There is no need to insert a breakpoint if an unconditional
         raw/sss breakpoint is already inserted at that location.  */
       sss_slot = find_single_step_breakpoint (bp_tgt->placed_address_space,
-                                             bp_tgt->placed_address);
+                                             bp_tgt->reqstd_address);
       if (sss_slot >= 0)
        {
          struct bp_target_info *sss_bp_tgt = single_step_breakpoints[sss_slot];
@@ -13315,7 +13341,7 @@ bkpt_remove_location (struct bp_location *bl)
     {
       struct bp_target_info *bp_tgt = &bl->target_info;
       struct address_space *aspace = bp_tgt->placed_address_space;
-      CORE_ADDR address = bp_tgt->placed_address;
+      CORE_ADDR address = bp_tgt->reqstd_address;
 
       /* Only remove the breakpoint if there is no raw/sss breakpoint
         still inserted at this location.  Otherwise, we would be
@@ -15338,7 +15364,7 @@ deprecated_insert_raw_breakpoint (struct gdbarch *gdbarch,
   bp_tgt = XCNEW (struct bp_target_info);
 
   bp_tgt->placed_address_space = aspace;
-  bp_tgt->placed_address = pc;
+  bp_tgt->reqstd_address = pc;
 
   /* If an unconditional non-raw breakpoint is already inserted at
      that location, there's no need to insert another.  However, with
@@ -15375,7 +15401,7 @@ deprecated_remove_raw_breakpoint (struct gdbarch *gdbarch, void *bp)
 {
   struct bp_target_info *bp_tgt = bp;
   struct address_space *aspace = bp_tgt->placed_address_space;
-  CORE_ADDR address = bp_tgt->placed_address;
+  CORE_ADDR address = bp_tgt->reqstd_address;
   struct bp_location *bl;
   int ret;
 
@@ -15517,7 +15543,7 @@ find_single_step_breakpoint (struct address_space *aspace,
       struct bp_target_info *bp_tgt = single_step_breakpoints[i];
       if (bp_tgt
          && breakpoint_address_match (bp_tgt->placed_address_space,
-                                      bp_tgt->placed_address,
+                                      bp_tgt->reqstd_address,
                                       aspace, pc))
        return i;
     }
@@ -16104,7 +16130,7 @@ save_breakpoints (char *filename, int from_tty,
       }
 
     if (tp->enable_state == bp_disabled)
-      fprintf_unfiltered (fp, "disable\n");
+      fprintf_unfiltered (fp, "disable $bpnum\n");
 
     /* If this is a multi-location breakpoint, check if the locations
        should be individually disabled.  Watchpoint locations are
@@ -17020,18 +17046,15 @@ a warning will be emitted for such breakpoints."),
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
 
-  add_setshow_auto_boolean_cmd ("always-inserted", class_support,
-                               &always_inserted_mode, _("\
+  add_setshow_boolean_cmd ("always-inserted", class_support,
+                          &always_inserted_mode, _("\
 Set mode for inserting breakpoints."), _("\
 Show mode for inserting breakpoints."), _("\
-When this mode is off, breakpoints are inserted in inferior when it is\n\
-resumed, and removed when execution stops.  When this mode is on,\n\
-breakpoints are inserted immediately and removed only when the user\n\
-deletes the breakpoint.  When this mode is auto (which is the default),\n\
-the behaviour depends on the non-stop setting (see help set non-stop).\n\
-In this case, if gdb is controlling the inferior in non-stop mode, gdb\n\
-behaves as if always-inserted mode is on; if gdb is controlling the\n\
-inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
+When this mode is on, breakpoints are inserted immediately as soon as\n\
+they're created, kept inserted even when execution stops, and removed\n\
+only when the user deletes them.  When this mode is off (the default),\n\
+breakpoints are inserted only when execution continues, and removed\n\
+when execution stops."),
                                NULL,
                                &show_always_inserted_mode,
                                &breakpoint_set_cmdlist,