From 765dc01564a52c8e8ef896ec4acef04a38d60377 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 22 Nov 2006 10:43:34 +0000 Subject: [PATCH] 2006-11-22 Vladimir Prus * 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 | 11 ++++++ gdb/Makefile.in | 3 +- gdb/breakpoint.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ gdb/doc/ChangeLog | 6 ++++ gdb/doc/gdb.texinfo | 26 ++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2f6ef8d0cd0..6171628abca 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2006-11-22 Vladimir Prus + + * 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 * memattr.h (enum mem_access_mode): New value diff --git a/gdb/Makefile.in b/gdb/Makefile.in index d28dc0820fc..869dd790252 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 92102ce605c..a2a4d196cbc 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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; } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 71f30c1e730..e217675932d 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2006-11-22 Vladimir Prus + + * gdb.texinfo (Setting breakpoints): Document + automatic software/hardware breakpoint usage and + the "set breakpoint auto-hw" command. + 2006-11-21 Vladimir Prus * gdb.texinfo (Memory Access Checking): New. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f89cc097816..82571b6c972 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 -- 2.30.2