2006-11-22 Vladimir Prus <vladimir@codesourcery.com>
authorVladimir Prus <vladimir@codesourcery.com>
Wed, 22 Nov 2006 10:43:34 +0000 (10:43 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Wed, 22 Nov 2006 10:43:34 +0000 (10:43 +0000)
        * breakpoint.c: Include "memattr.h".
        (automatic_hardware_breakpoints): New.
        (show_automatic_hardware_breakpoints): New.
        (insert_bp_location): Automatically use
        hardware breakpoints.
        (_initialize_breakpoint): Register the "auto-hw"
        variable.
        * Makefile.in (breakpoint.o): Update dependencies.

gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo

index 2f6ef8d0cd0d5a0d864e3b2553eab1d90ac8d9b8..6171628abca43c80118ccdbdbf45d65a2ec7bd81 100644 (file)
@@ -1,3 +1,14 @@
+2006-11-22  Vladimir Prus  <vladimir@codesourcery.com>
+
+       * breakpoint.c: Include "memattr.h".
+       (automatic_hardware_breakpoints): New.
+       (show_automatic_hardware_breakpoints): New.
+       (insert_bp_location): Automatically use
+       hardware breakpoints.
+       (_initialize_breakpoint): Register the "auto-hw"
+       variable.
+       * Makefile.in (breakpoint.o): Update dependencies.
+
 2006-11-21  Vladimir Prus  <vladimir@codesourcery.com>
 
        * memattr.h (enum mem_access_mode): New value
index d28dc0820fcc35636d2cf6d8c03f6f294cd06d02..869dd7902520cbe4c45a1fa01d3442026126e63e 100644 (file)
@@ -1834,7 +1834,8 @@ breakpoint.o: breakpoint.c $(defs_h) $(symtab_h) $(frame_h) $(breakpoint_h) \
        $(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_h) \
        $(objfiles_h) $(source_h) $(linespec_h) $(completer_h) $(gdb_h) \
        $(ui_out_h) $(cli_script_h) $(gdb_assert_h) $(block_h) $(solib_h) \
-       $(solist_h) $(observer_h) $(exceptions_h) $(gdb_events_h) $(mi_common_h)
+       $(solist_h) $(observer_h) $(exceptions_h) $(gdb_events_h) $(mi_common_h) \
+       $(memattr_h)
 bsd-kvm.o: bsd-kvm.c $(defs_h) $(cli_cmds_h) $(command_h) $(frame_h) \
        $(regcache_h) $(target_h) $(value_h) $(gdbcore_h) $(gdb_assert_h) \
        $(readline_h) $(bsd_kvm_h)
index 92102ce605cd22c4d7e540d0b965e3b83dfff2b2..a2a4d196cbcf698bdb17f98b37ca7a599ffc38d1 100644 (file)
@@ -53,6 +53,7 @@
 #include "solist.h"
 #include "observer.h"
 #include "exceptions.h"
+#include "memattr.h"
 
 #include "gdb-events.h"
 #include "mi/mi-common.h"
@@ -231,6 +232,22 @@ Debugger's behavior regarding pending breakpoints is %s.\n"),
                    value);
 }
 
+/* If 1, gdb will automatically use hardware breakpoints for breakpoints
+   set with "break" but falling in read-only memory. 
+   If 0, gdb will warn about such breakpoints, but won't automatically
+   use hardware breakpoints.  */
+static int automatic_hardware_breakpoints;
+static void
+show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
+                                    struct cmd_list_element *c,
+                                    const char *value)
+{
+  fprintf_filtered (file, _("\
+Automatic usage of hardware breakpoints is %s.\n"),
+                   value);
+}
+
+
 void _initialize_breakpoint (void);
 
 extern int addressprint;       /* Print machine addresses? */
@@ -794,6 +811,57 @@ insert_bp_location (struct bp_location *bpt,
   if (bpt->loc_type == bp_loc_software_breakpoint
       || bpt->loc_type == bp_loc_hardware_breakpoint)
     {
+      if (bpt->owner->type != bp_hardware_breakpoint)
+       {
+         /* If the explicitly specified breakpoint type
+            is not hardware breakpoint, check the memory map to see
+            if the breakpoint address is in read only memory or not.
+            Two important cases are:
+            - location type is not hardware breakpoint, memory
+            is readonly.  We change the type of the location to
+            hardware breakpoint.
+            - location type is hardware breakpoint, memory is read-write.
+            This means we've previously made the location hardware one, but
+            then the memory map changed, so we undo.
+            
+            When breakpoints are removed, remove_breakpoints will
+            use location types we've just set here, the only possible
+            problem is that memory map has changed during running program,
+            but it's not going to work anyway with current gdb.  */
+         struct mem_region *mr 
+           = lookup_mem_region (bpt->target_info.placed_address);
+         
+         if (mr)
+           {
+             if (automatic_hardware_breakpoints)
+               {
+                 int changed = 0;
+                 enum bp_loc_type new_type;
+                 
+                 if (mr->attrib.mode != MEM_RW)
+                   new_type = bp_loc_hardware_breakpoint;
+                 else 
+                   new_type = bp_loc_software_breakpoint;
+                 
+                 if (new_type != bpt->loc_type)
+                   {
+                     static int said = 0;
+                     bpt->loc_type = new_type;
+                     if (!said)
+                       {
+                         fprintf_filtered (gdb_stdout, _("\
+Note: automatically using hardware breakpoints for read-only addresses."));
+                         said = 1;
+                       }
+                   }
+               }
+             else if (bpt->loc_type == bp_loc_software_breakpoint
+                      && mr->attrib.mode != MEM_RW)        
+               warning (_("cannot set software breakpoint at readonly address %s"),
+                        paddr (bpt->address));
+           }
+       }
+        
       /* First check to see if we have to handle an overlay.  */
       if (overlay_debugging == ovly_off
          || bpt->section == NULL
@@ -1235,6 +1303,9 @@ reattach_breakpoints (int pid)
     if (b->inserted)
       {
        remove_breakpoint (b, mark_inserted);
+       /* Note: since we insert a breakpoint right after removing,
+          any decisions about automatically using hardware breakpoints
+          made in insert_bp_location are preserved.  */
        if (b->loc_type == bp_loc_hardware_breakpoint)
          val = target_insert_hw_breakpoint (&b->target_info);
        else
@@ -8127,4 +8198,18 @@ user-query to see if a pending breakpoint should be created."),
                                &breakpoint_show_cmdlist);
 
   pending_break_support = AUTO_BOOLEAN_AUTO;
+
+  add_setshow_boolean_cmd ("auto-hw", no_class,
+                          &automatic_hardware_breakpoints, _("\
+Set automatic usage of hardware breakpoints."), _("\
+Show automatic usage of hardware breakpoints."), _("\
+If set, the debugger will automatically use hardware breakpoints for\n\
+breakpoints set with \"break\" but falling in read-only memory.  If not set,\n\
+a warning will be emitted for such breakpoints."),
+                          NULL,
+                          show_automatic_hardware_breakpoints,
+                          &breakpoint_set_cmdlist,
+                          &breakpoint_show_cmdlist);
+  
+  automatic_hardware_breakpoints = 1;
 }
index 71f30c1e730da0e6859db97d293c2223dda3710b..e217675932d356fa0618a720c7ef8c0fa73ffc4d 100644 (file)
@@ -1,3 +1,9 @@
+2006-11-22  Vladimir Prus  <vladimir@codesourcery.com>
+        
+       * gdb.texinfo (Setting breakpoints): Document
+        automatic software/hardware breakpoint usage and
+        the "set breakpoint auto-hw" command.
+
 2006-11-21  Vladimir Prus  <vladimir@codesourcery.com>
 
        * gdb.texinfo (Memory Access Checking): New.
index f89cc09781682007bc6d3716d347d70627fb7a80..82571b6c9728a330428aa4950a8d077175d9eb46 100644 (file)
@@ -3099,6 +3099,32 @@ This is done because any number of shared library loads could have
 occurred since the time the breakpoint was disabled and one or more
 of these loads could resolve the location.
 
+@cindex automatic hardware breakpoints
+For some targets, @value{GDBN} can automatically decide if hardware or
+software breakpoints should be used, depending on whether the
+breakpoint address is read-only or read-write.  This applies to
+breakpoints set with the @code{break} command as well as to internal
+breakpoints set by commands like @code{next} and @code{finish}.  For
+breakpoints set with @code{hbreak}, @value{GDBN} will always use hardware 
+breakpoints.
+
+You can control this automatic behaviour with the following commands::
+
+@kindex set breakpoint auto-hw
+@kindex show breakpoint auto-hw
+@table @code
+@item set breakpoint auto-hw on
+This is the default behavior.  When @value{GDBN} sets a breakpoint, it
+will try to use the target memory map to decide if software or hardware
+breakpoint must be used.
+
+@item set breakpoint auto-hw off
+This indicates @value{GDBN} should not automatically select breakpoint
+type.  If the target provides a memory map, @value{GDBN} will warn when
+trying to set software breakpoint at a read-only address.
+@end table
+
+
 @cindex negative breakpoint numbers
 @cindex internal @value{GDBN} breakpoints
 @value{GDBN} itself sometimes sets breakpoints in your program for