X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fbreakpoint.c;h=5e36d93acd69788f28ffbc212411905d45955f6a;hb=17a912b6825ef7feaad6d9b4f5419f045fe3c8d0;hp=76c73d7b9c310f6cf7ac7822c3b72a1a801a54ce;hpb=47b667dea5dd1f1c4fc7a1304163c254ffa16161;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 76c73d7b9c..5e36d93acd 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1,7 +1,7 @@ /* Everything about breakpoints, for GDB. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. @@ -18,8 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include @@ -53,8 +53,11 @@ #include "solist.h" #include "observer.h" #include "exceptions.h" +#include "memattr.h" +#include "ada-lang.h" #include "gdb-events.h" +#include "mi/mi-common.h" /* Prototypes for local functions. */ @@ -101,7 +104,7 @@ static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int); static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr, enum bptype bptype); -static void describe_other_breakpoints (CORE_ADDR, asection *); +static void describe_other_breakpoints (CORE_ADDR, asection *, int); static void breakpoints_info (char *, int); @@ -199,6 +202,8 @@ static void tcatch_command (char *arg, int from_tty); static void ep_skip_leading_whitespace (char **s); +static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc); + /* Prototypes for exported functions. */ /* If FALSE, gdb will not use hardware support for watchpoints, even @@ -230,6 +235,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? */ @@ -277,14 +298,6 @@ int breakpoint_count; /* Pointer to current exception event record */ static struct exception_event_record *current_exception_event; -/* Indicator of whether exception catchpoints should be nuked between - runs of a program. */ -int deprecated_exception_catchpoints_are_fragile = 0; - -/* Indicator of when exception catchpoints set-up should be - reinitialized -- e.g. when program is re-run. */ -int deprecated_exception_support_initialized = 0; - /* This function returns a pointer to the string representation of the pathname of the dynamically-linked library that has just been loaded. @@ -384,6 +397,8 @@ int default_breakpoint_line; Currently the string can either be a number or "$" followed by the name of a convenience variable. Making it an expression wouldn't work well for map_breakpoint_numbers (e.g. "4 + 5 + 6"). + + If the string is a NULL pointer, that denotes the last breakpoint. TRAILER is a character which can be found after the number; most commonly this is `-'. If you don't want a trailer, use \0. */ @@ -628,6 +643,52 @@ commands_command (char *arg, int from_tty) } error (_("No breakpoint number %d."), bnum); } + +/* Like commands_command, but instead of reading the commands from + input stream, takes them from an already parsed command structure. + + This is used by cli-script.c to DTRT with breakpoint commands + that are part of if and while bodies. */ +enum command_control_type +commands_from_control_command (char *arg, struct command_line *cmd) +{ + struct breakpoint *b; + char *p; + int bnum; + + /* If we allowed this, we would have problems with when to + free the storage, if we change the commands currently + being read from. */ + + if (executing_breakpoint_commands) + error (_("Can't use the \"commands\" command among a breakpoint's commands.")); + + /* An empty string for the breakpoint number means the last + breakpoint, but get_number expects a NULL pointer. */ + if (arg && !*arg) + p = NULL; + else + p = arg; + bnum = get_number (&p); + + if (p && *p) + error (_("Unexpected extra arguments following breakpoint number.")); + + ALL_BREAKPOINTS (b) + if (b->number == bnum) + { + free_command_lines (&b->commands); + if (cmd->body_count != 1) + error (_("Invalid \"commands\" block structure.")); + /* We need to copy the commands because if/while will free the + list after it finishes execution. */ + b->commands = copy_command_lines (cmd->body_list[0]); + breakpoints_changed (); + breakpoint_modify_event (b->number); + return simple_control; + } + error (_("No breakpoint number %d."), bnum); +} /* Like target_read_memory() but if breakpoints are inserted, return the shadow contents instead of the breakpoints themselves. @@ -638,15 +699,14 @@ commands_command (char *arg, int from_tty) shadow contents, not the breakpoints themselves. From breakpoint.c. */ int -deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, - unsigned len) +read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len) { int status; struct bp_location *b; CORE_ADDR bp_addr = 0; int bp_size = 0; - if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL) + if (gdbarch_breakpoint_from_pc (current_gdbarch, &bp_addr, &bp_size) == NULL) /* No breakpoints on this machine. */ return target_read_memory (memaddr, myaddr, len); @@ -662,16 +722,10 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, continue; /* Addresses and length of the part of the breakpoint that we need to copy. */ - /* XXXX The m68k, sh and h8300 have different local and remote - breakpoint values. BREAKPOINT_FROM_PC still manages to - correctly determine the breakpoints memory address and size - for these targets. */ - bp_addr = b->address; - bp_size = 0; - if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL) - continue; + bp_addr = b->target_info.placed_address; + bp_size = b->target_info.shadow_len; if (bp_size == 0) - /* bp isn't valid */ + /* bp isn't valid, or doesn't shadow memory. */ continue; if (bp_addr + bp_size <= memaddr) /* The breakpoint is entirely before the chunk of memory we @@ -702,12 +756,12 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, } memcpy (myaddr + bp_addr - memaddr, - b->shadow_contents + bptoffset, bp_size); + b->target_info.shadow_contents + bptoffset, bp_size); if (bp_addr > memaddr) { /* Copy the section of memory before the breakpoint. */ - status = deprecated_read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr); + status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr); if (status != 0) return status; } @@ -715,7 +769,7 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, if (bp_addr + bp_size < memaddr + len) { /* Copy the section of memory after the breakpoint. */ - status = deprecated_read_memory_nobpt (bp_addr + bp_size, + status = read_memory_nobpt (bp_addr + bp_size, myaddr + bp_addr + bp_size - memaddr, memaddr + len - (bp_addr + bp_size)); if (status != 0) @@ -755,7 +809,8 @@ insert_catchpoint (struct ui_out *uo, void *args) /* Helper routine: free the value chain for a breakpoint (watchpoint). */ -static void free_valchain (struct bp_location *b) +static void +free_valchain (struct bp_location *b) { struct value *v; struct value *n; @@ -792,9 +847,64 @@ insert_bp_location (struct bp_location *bpt, if (bpt->inserted || bpt->duplicate) return 0; + /* Initialize the target-specific information. */ + memset (&bpt->target_info, 0, sizeof (bpt->target_info)); + bpt->target_info.placed_address = bpt->address; + 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.\n")); + 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 @@ -803,11 +913,9 @@ insert_bp_location (struct bp_location *bpt, /* No overlay handling: just set the breakpoint. */ if (bpt->loc_type == bp_loc_hardware_breakpoint) - val = target_insert_hw_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_hw_breakpoint (&bpt->target_info); else - val = target_insert_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); } else { @@ -826,7 +934,9 @@ insert_bp_location (struct bp_location *bpt, CORE_ADDR addr = overlay_unmapped_address (bpt->address, bpt->section); /* Set a software (trap) breakpoint at the LMA. */ - val = target_insert_breakpoint (addr, bpt->shadow_contents); + bpt->overlay_target_info = bpt->target_info; + bpt->overlay_target_info.placed_address = addr; + val = target_insert_breakpoint (&bpt->overlay_target_info); if (val != 0) fprintf_unfiltered (tmp_error_stream, "Overlay breakpoint %d failed: in ROM?", @@ -838,11 +948,9 @@ insert_bp_location (struct bp_location *bpt, { /* Yes. This overlay section is mapped into memory. */ if (bpt->loc_type == bp_loc_hardware_breakpoint) - val = target_insert_hw_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_hw_breakpoint (&bpt->target_info); else - val = target_insert_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); } else { @@ -931,7 +1039,7 @@ insert_bp_location (struct bp_location *bpt, /* FIXME drow/2003-09-09: It would be nice if evaluate_expression took a frame parameter, so that we didn't have to change the selected frame. */ - saved_frame_id = get_frame_id (deprecated_selected_frame); + saved_frame_id = get_frame_id (get_selected_frame (NULL)); /* Determine if the watchpoint is within scope. */ if (bpt->owner->exp_valid_block == NULL) @@ -1044,7 +1152,7 @@ in which its expression is valid.\n"), /* If we get here, we must have a callback mechanism for exception events -- with g++ style embedded label support, we insert ordinary breakpoints and not catchpoints. */ - val = target_insert_breakpoint (bpt->address, bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); if (val) { /* Couldn't set breakpoint for some reason */ @@ -1141,6 +1249,12 @@ insert_breakpoints (void) if (!breakpoint_enabled (b->owner)) continue; + /* There is no point inserting thread-specific breakpoints if the + thread no longer exists. */ + if (b->owner->thread != -1 + && !valid_thread_id (b->owner->thread)) + continue; + /* FIXME drow/2003-10-07: This code should be pushed elsewhere when hardware watchpoints are split into multiple loc breakpoints. */ if ((b->loc_type == bp_loc_hardware_watchpoint @@ -1232,10 +1346,13 @@ 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->address, b->shadow_contents); + val = target_insert_hw_breakpoint (&b->target_info); else - val = target_insert_breakpoint (b->address, b->shadow_contents); + val = target_insert_breakpoint (&b->target_info); /* FIXME drow/2003-10-07: This doesn't handle any other kinds of breakpoints. It's wrong for watchpoints, for example. */ if (val != 0) @@ -1284,13 +1401,6 @@ update_breakpoints_after_exec (void) continue; } - /* Ditto the sigtramp handler breakpoints. */ - if (b->type == bp_through_sigtramp) - { - delete_breakpoint (b); - continue; - } - /* Ditto the exception-handling catchpoints. */ if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw)) { @@ -1324,7 +1434,7 @@ update_breakpoints_after_exec (void) (b->type == bp_catch_vfork) || (b->type == bp_catch_fork)) { - b->loc->address = (CORE_ADDR) NULL; + b->loc->address = (CORE_ADDR) 0; continue; } @@ -1377,7 +1487,7 @@ update_breakpoints_after_exec (void) unnecessary. A call to breakpoint_re_set_one always recomputes the breakpoint's address from scratch, or deletes it if it can't. So I think this assignment could be deleted without effect. */ - b->loc->address = (CORE_ADDR) NULL; + b->loc->address = (CORE_ADDR) 0; } /* FIXME what about longjmp breakpoints? Re-create them here? */ create_overlay_event_breakpoint ("_ovly_debug_event"); @@ -1439,10 +1549,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) /* No overlay handling: just remove the breakpoint. */ if (b->loc_type == bp_loc_hardware_breakpoint) - val = target_remove_hw_breakpoint (b->address, - b->shadow_contents); + val = target_remove_hw_breakpoint (&b->target_info); else - val = target_remove_breakpoint (b->address, b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); } else { @@ -1453,14 +1562,12 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) /* Yes -- overlay event support is not active, so we should have set a breakpoint at the LMA. Remove it. */ - CORE_ADDR addr = overlay_unmapped_address (b->address, - b->section); /* Ignore any failures: if the LMA is in ROM, we will have already warned when we failed to insert it. */ if (b->loc_type == bp_loc_hardware_breakpoint) - target_remove_hw_breakpoint (addr, b->shadow_contents); + target_remove_hw_breakpoint (&b->overlay_target_info); else - target_remove_breakpoint (addr, b->shadow_contents); + target_remove_breakpoint (&b->overlay_target_info); } /* Did we set a breakpoint at the VMA? If so, we will have marked the breakpoint 'inserted'. */ @@ -1471,11 +1578,15 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) unmapped, but let's not rely on that being safe. We don't know what the overlay manager might do. */ if (b->loc_type == bp_loc_hardware_breakpoint) - val = target_remove_hw_breakpoint (b->address, - b->shadow_contents); + val = target_remove_hw_breakpoint (&b->target_info); + + /* However, we should remove *software* breakpoints only + if the section is still mapped, or else we overwrite + wrong code with the saved shadow contents. */ + else if (section_is_mapped (b->section)) + val = target_remove_breakpoint (&b->target_info); else - val = target_remove_breakpoint (b->address, - b->shadow_contents); + val = 0; } else { @@ -1563,24 +1674,11 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) && breakpoint_enabled (b->owner) && !b->duplicate) { - - val = target_remove_breakpoint (b->address, b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); if (val) return val; b->inserted = (is == mark_inserted); } - else if (ep_is_exception_catchpoint (b->owner) - && b->inserted /* sometimes previous insert doesn't happen */ - && breakpoint_enabled (b->owner) - && !b->duplicate) - { - - val = target_remove_breakpoint (b->address, b->shadow_contents); - if (val) - return val; - - b->inserted = (is == mark_inserted); - } return 0; } @@ -1613,7 +1711,6 @@ breakpoint_init_inferior (enum inf_context context) { struct breakpoint *b, *temp; struct bp_location *bpt; - static int warning_needed = 0; ALL_BP_LOCATIONS (bpt) bpt->inserted = 0; @@ -1651,28 +1748,9 @@ breakpoint_init_inferior (enum inf_context context) } break; default: - /* Likewise for exception catchpoints in dynamic-linked - executables where required */ - if (ep_is_exception_catchpoint (b) - && deprecated_exception_catchpoints_are_fragile) - { - warning_needed = 1; - delete_breakpoint (b); - } break; } } - - if (deprecated_exception_catchpoints_are_fragile) - deprecated_exception_support_initialized = 0; - - /* Don't issue the warning unless it's really needed... */ - if (warning_needed && (context != inf_exited)) - { - warning (_("Exception catchpoints from last run were deleted.\n" - "You must reinsert them explicitly.")); - warning_needed = 0; - } } /* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint @@ -1743,6 +1821,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc) } } + /* Also check for software single-step breakpoints. */ + if (single_step_breakpoint_inserted_here_p (pc)) + return 1; + return 0; } @@ -1774,6 +1856,10 @@ software_breakpoint_inserted_here_p (CORE_ADDR pc) } } + /* Also check for software single-step breakpoints. */ + if (single_step_breakpoint_inserted_here_p (pc)) + return 1; + return 0; } @@ -1949,28 +2035,30 @@ bpstat_find_step_resume_breakpoint (bpstat bsp) } -/* Return the breakpoint number of the first breakpoint we are stopped +/* 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 good for anything but further calls to bpstat_num). - Return 0 if passed a bpstat which does not indicate any breakpoints. */ + Return 0 if passed a bpstat which does not indicate any breakpoints. + Return -1 if stopped at a breakpoint that has been deleted since + we set it. + Return 1 otherwise. */ int -bpstat_num (bpstat *bsp) +bpstat_num (bpstat *bsp, int *num) { struct breakpoint *b; if ((*bsp) == NULL) return 0; /* No more breakpoint values */ - else - { - b = (*bsp)->breakpoint_at; - *bsp = (*bsp)->next; - if (b == NULL) - return -1; /* breakpoint that's been deleted since */ - else - return b->number; /* We have its number */ - } + + b = (*bsp)->breakpoint_at; + *bsp = (*bsp)->next; + if (b == NULL) + return -1; /* breakpoint that's been deleted since */ + + *num = b->number; /* We have its number */ + return 1; } /* Modify BS so that the actions will not be performed. */ @@ -2114,7 +2202,8 @@ print_it_typical (bpstat bs) annotate_breakpoint (bs->breakpoint_at->number); ui_out_text (uiout, "\nBreakpoint "); if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "breakpoint-hit"); + ui_out_field_string (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT)); ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number); ui_out_text (uiout, ", "); return PRINT_SRC_AND_LOC; @@ -2249,7 +2338,9 @@ print_it_typical (bpstat bs) { annotate_watchpoint (bs->breakpoint_at->number); if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "watchpoint-trigger"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER)); mention (bs->breakpoint_at); ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); @@ -2269,7 +2360,9 @@ print_it_typical (bpstat bs) case bp_read_watchpoint: if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "read-watchpoint-trigger"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER)); mention (bs->breakpoint_at); ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); @@ -2285,7 +2378,9 @@ print_it_typical (bpstat bs) { annotate_watchpoint (bs->breakpoint_at->number); if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER)); mention (bs->breakpoint_at); ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); @@ -2299,7 +2394,9 @@ print_it_typical (bpstat bs) { mention (bs->breakpoint_at); if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER)); ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); } @@ -2315,13 +2412,17 @@ print_it_typical (bpstat bs) case bp_finish: if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "function-finished"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED)); return PRINT_UNKNOWN; break; case bp_until: if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "location-reached"); + ui_out_field_string + (uiout, "reason", + async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED)); return PRINT_UNKNOWN; break; @@ -2329,7 +2430,6 @@ print_it_typical (bpstat bs) case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: - case bp_through_sigtramp: case bp_watchpoint_scope: case bp_call_dummy: default: @@ -2484,6 +2584,13 @@ watchpoint_check (void *p) reinit_frame_cache (); fr = frame_find_by_id (b->watchpoint_frame); within_current_scope = (fr != NULL); + + /* If we've gotten confused in the unwinder, we might have + returned a frame that can't describe this variable. */ + if (within_current_scope + && block_function (b->exp_valid_block) != get_frame_function (fr)) + within_current_scope = 0; + /* in_function_epilogue_p() returns a non-zero value if we're still in the function but the stack frame has already been invalidated. Since we can't rely on the values of local variables after the @@ -2545,7 +2652,8 @@ watchpoint_check (void *p) will be deleted already. So we have no choice but print the information here. */ if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "reason", "watchpoint-scope"); + ui_out_field_string + (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE)); ui_out_text (uiout, "\nWatchpoint "); ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number); ui_out_text (uiout, " deleted because the program has left the block in\n\ @@ -2938,9 +3046,6 @@ bpstat_what (bpstat bs) /* We hit the step_resume breakpoint. */ step_resume, - /* We hit the through_sigtramp breakpoint. */ - through_sig, - /* We hit the shared library event breakpoint. */ shlib_event, @@ -2962,7 +3067,6 @@ bpstat_what (bpstat bs) #define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME #define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE #define sr BPSTAT_WHAT_STEP_RESUME -#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP #define shl BPSTAT_WHAT_CHECK_SHLIBS #define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK @@ -2985,17 +3089,16 @@ bpstat_what (bpstat bs) back and decide something of a lower priority is better. The ordering is: - kc < clr sgl shl shlr slr sn sr ss ts - sgl < clrs shl shlr slr sn sr ss ts - slr < err shl shlr sn sr ss ts - clr < clrs err shl shlr sn sr ss ts - clrs < err shl shlr sn sr ss ts - ss < shl shlr sn sr ts - sn < shl shlr sr ts - sr < shl shlr ts - shl < shlr - ts < - shlr < + kc < clr sgl shl shlr slr sn sr ss + sgl < clrs shl shlr slr sn sr ss + slr < err shl shlr sn sr ss + clr < clrs err shl shlr sn sr ss + clrs < err shl shlr sn sr ss + ss < shl shlr sn sr + sn < shl shlr sr + shl < shlr sr + shlr < sr + sr < What I think this means is that we don't need a damned table here. If you just put the rows and columns in the right order, @@ -3008,39 +3111,35 @@ bpstat_what (bpstat bs) /* step_resume entries: a step resume breakpoint overrides another breakpoint of signal handling (see comment in wait_for_inferior at where we set the step_resume breakpoint). */ - /* We handle the through_sigtramp_breakpoint the same way; having both - one of those and a step_resume_breakpoint is probably very rare (?). */ static const enum bpstat_what_main_action table[(int) class_last][(int) BPSTAT_WHAT_LAST] = { /* old action */ - /* kc ss sn sgl slr clr clrs sr ts shl shlr + /* kc ss sn sgl slr clr clrs sr shl shlr */ /*no_effect */ - {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl, shlr}, + {kc, ss, sn, sgl, slr, clr, clrs, sr, shl, shlr}, /*wp_silent */ - {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr}, + {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr}, /*wp_noisy */ - {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr}, + {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr}, /*bp_nostop */ - {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl, shlr}, + {sgl, ss, sn, sgl, slr, clrs, clrs, sr, shl, shlr}, /*bp_silent */ - {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr}, + {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr}, /*bp_noisy */ - {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr}, + {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr}, /*long_jump */ - {slr, ss, sn, slr, slr, err, err, sr, ts, shl, shlr}, + {slr, ss, sn, slr, slr, err, err, sr, shl, shlr}, /*long_resume */ - {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr}, + {clr, ss, sn, clrs, err, err, err, sr, shl, shlr}, /*step_resume */ - {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr}, -/*through_sig */ - {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr}, + {sr, sr, sr, sr, sr, sr, sr, sr, sr, sr}, /*shlib */ - {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr}, + {shl, shl, shl, shl, shl, shl, shl, sr, shl, shlr}, /*catch_shlib */ - {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr} + {shlr, shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr} }; #undef kc @@ -3116,9 +3215,6 @@ bpstat_what (bpstat bs) /* It is for the wrong frame. */ bs_class = bp_nostop; break; - case bp_through_sigtramp: - bs_class = through_sig; - break; case bp_watchpoint_scope: bs_class = bp_nostop; break; @@ -3296,7 +3392,6 @@ print_one_breakpoint (struct breakpoint *b, {bp_longjmp, "longjmp"}, {bp_longjmp_resume, "longjmp resume"}, {bp_step_resume, "step resume"}, - {bp_through_sigtramp, "sigtramp"}, {bp_watchpoint_scope, "watchpoint scope"}, {bp_call_dummy, "call dummy"}, {bp_shlib_event, "shlib events"}, @@ -3348,7 +3443,7 @@ print_one_breakpoint (struct breakpoint *b, strcpy (wrap_indent, " "); if (addressprint) { - if (TARGET_ADDR_BIT <= 32) + if (gdbarch_addr_bit (current_gdbarch) <= 32) strcat (wrap_indent, " "); else strcat (wrap_indent, " "); @@ -3413,6 +3508,7 @@ print_one_breakpoint (struct breakpoint *b, ui_out_field_int (uiout, "what", b->forked_inferior_pid); ui_out_spaces (uiout, 1); } + break; case bp_catch_exec: /* Field 4, the address, is omitted (which makes the columns @@ -3458,7 +3554,6 @@ print_one_breakpoint (struct breakpoint *b, case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: - case bp_through_sigtramp: case bp_watchpoint_scope: case bp_call_dummy: case bp_shlib_event: @@ -3487,6 +3582,16 @@ print_one_breakpoint (struct breakpoint *b, } ui_out_field_string (uiout, "file", b->source_file); ui_out_text (uiout, ":"); + + if (ui_out_is_mi_like_p (uiout)) + { + struct symtab_and_line sal = find_pc_line (b->loc->address, 0); + char *fullname = symtab_to_fullname (sal.symtab); + + if (fullname) + ui_out_field_string (uiout, "fullname", fullname); + } + ui_out_field_int (uiout, "line", b->line_number); } else if (b->pending) @@ -3521,8 +3626,11 @@ print_one_breakpoint (struct breakpoint *b, ui_out_text (uiout, "\n"); } - if (b->cond) + if (b->cond && !ada_exception_catchpoint_p (b)) { + /* We do not print the condition for Ada exception catchpoints + because the condition is an internal implementation detail + that we do not want to expose to the user. */ annotate_field (7); ui_out_text (uiout, "\tstop only if "); print_expression (b->cond, stb->stream); @@ -3617,8 +3725,11 @@ gdb_breakpoint_query (struct ui_out *uiout, int bnum, char **error_message) args.bnum = bnum; /* For the moment we don't trust print_one_breakpoint() to not throw an error. */ - return catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args, - error_message, RETURN_MASK_ALL); + if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args, + error_message, RETURN_MASK_ALL) < 0) + return GDB_RC_FAIL; + else + return GDB_RC_OK; } /* Return non-zero if B is user settable (breakpoints, watchpoints, @@ -3691,7 +3802,7 @@ breakpoint_1 (int bnum, int allflag) { if (nr_printable_breakpoints > 0) annotate_field (4); - if (TARGET_ADDR_BIT <= 32) + if (gdbarch_addr_bit (current_gdbarch) <= 32) ui_out_table_header (uiout, 10, ui_left, "addr", "Address");/* 5 */ else ui_out_table_header (uiout, 18, ui_left, "addr", "Address");/* 5 */ @@ -3761,7 +3872,7 @@ maintenance_info_breakpoints (char *bnum_exp, int from_tty) /* Print a message describing any breakpoints set at PC. */ static void -describe_other_breakpoints (CORE_ADDR pc, asection *section) +describe_other_breakpoints (CORE_ADDR pc, asection *section, int thread) { int others = 0; struct breakpoint *b; @@ -3781,12 +3892,16 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section) if (!b->pending && (!overlay_debugging || b->loc->section == section)) { others--; - printf_filtered ("%d%s%s ", - b->number, + printf_filtered ("%d", b->number); + if (b->thread == -1 && thread != -1) + printf_filtered (" (all threads)"); + else if (b->thread != -1) + printf_filtered (" (thread %d)", b->thread); + printf_filtered ("%s%s ", ((b->enable_state == bp_disabled || b->enable_state == bp_shlib_disabled || b->enable_state == bp_call_disabled) - ? " (disabled)" + ? " (disabled)" : b->enable_state == bp_permanent ? " (permanent)" : ""), @@ -3999,7 +4114,6 @@ allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type) case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: - case bp_through_sigtramp: case bp_watchpoint_scope: case bp_call_dummy: case bp_shlib_event: @@ -4063,13 +4177,23 @@ struct breakpoint * set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype) { struct breakpoint *b, *b1; + CORE_ADDR adjusted_address; b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint)); memset (b, 0, sizeof (*b)); + + /* Adjust the breakpoint's address prior to allocating a location. + Once we call allocate_bp_location(), that mostly uninitialized + location will be placed on the location chain. Adjustment of the + breakpoint may cause read_memory_nobpt() to be called and we do + not want its scan of the location chain to find a breakpoint and + location that's only been partially initialized. */ + adjusted_address = adjust_breakpoint_address (sal.pc, bptype); + b->loc = allocate_bp_location (b, bptype); b->loc->requested_address = sal.pc; - b->loc->address = adjust_breakpoint_address (b->loc->requested_address, - bptype); + b->loc->address = adjusted_address; + if (sal.symtab == NULL) b->source_file = NULL; else @@ -4860,7 +4984,6 @@ mention (struct breakpoint *b) case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: - case bp_through_sigtramp: case bp_call_dummy: case bp_watchpoint_scope: case bp_shlib_event: @@ -4939,7 +5062,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string, struct symtab_and_line sal = sals.sals[i]; if (from_tty) - describe_other_breakpoints (sal.pc, sal.section); + describe_other_breakpoints (sal.pc, sal.section, thread); b = set_raw_breakpoint (sal, type); set_breakpoint_count (breakpoint_count + 1); @@ -5456,8 +5579,11 @@ gdb_breakpoint (char *address, char *condition, args.tempflag = tempflag; args.thread = thread; args.ignore_count = ignore_count; - return catch_exceptions_with_msg (uiout, do_captured_breakpoint, &args, - error_message, RETURN_MASK_ALL); + if (catch_exceptions_with_msg (uiout, do_captured_breakpoint, &args, + error_message, RETURN_MASK_ALL) < 0) + return GDB_RC_FAIL; + else + return GDB_RC_OK; } @@ -5778,11 +5904,6 @@ watch_command_1 (char *arg, int accessflag, int from_tty) in hardware. If the watchpoint can not be handled in hardware return zero. */ -#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT) -#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \ - (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN)) -#endif - static int can_use_hardware_watchpoint (struct value *v) { @@ -5914,7 +6035,8 @@ until_break_command (char *arg, int from_tty, int anywhere) { struct symtabs_and_lines sals; struct symtab_and_line sal; - struct frame_info *prev_frame = get_prev_frame (deprecated_selected_frame); + struct frame_info *frame = get_selected_frame (NULL); + struct frame_info *prev_frame = get_prev_frame (frame); struct breakpoint *breakpoint; struct cleanup *old_chain; struct continuation_arg *arg1; @@ -5950,8 +6072,7 @@ until_break_command (char *arg, int from_tty, int anywhere) else /* Otherwise, specify the current frame, because we want to stop only at the very same frame. */ - breakpoint = set_momentary_breakpoint (sal, - get_frame_id (deprecated_selected_frame), + breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_until); if (!target_can_async_p ()) @@ -6420,6 +6541,86 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, warning (_("Unsupported with this platform/compiler combination.")); } +/* Create a breakpoint struct for Ada exception catchpoints. */ + +static void +create_ada_exception_breakpoint (struct symtab_and_line sal, + char *addr_string, + char *exp_string, + char *cond_string, + struct expression *cond, + struct breakpoint_ops *ops, + int tempflag, + int from_tty) +{ + struct breakpoint *b; + + if (from_tty) + { + describe_other_breakpoints (sal.pc, sal.section, -1); + /* FIXME: brobecker/2006-12-28: Actually, re-implement a special + version for exception catchpoints, because two catchpoints + used for different exception names will use the same address. + In this case, a "breakpoint ... also set at..." warning is + unproductive. Besides. the warning phrasing is also a bit + inapropriate, we should use the word catchpoint, and tell + the user what type of catchpoint it is. The above is good + enough for now, though. */ + } + + b = set_raw_breakpoint (sal, bp_breakpoint); + set_breakpoint_count (breakpoint_count + 1); + + b->enable_state = bp_enabled; + b->disposition = tempflag ? disp_del : disp_donttouch; + b->number = breakpoint_count; + b->ignore_count = 0; + b->cond = cond; + b->addr_string = addr_string; + b->language = language_ada; + b->cond_string = cond_string; + b->exp_string = exp_string; + b->thread = -1; + b->ops = ops; + b->from_tty = from_tty; + + mention (b); +} + +/* Implement the "catch exception" command. */ + +static void +catch_ada_exception_command (char *arg, int tempflag, int from_tty) +{ + struct symtab_and_line sal; + enum bptype type; + char *addr_string = NULL; + char *exp_string = NULL; + char *cond_string = NULL; + struct expression *cond = NULL; + struct breakpoint_ops *ops = NULL; + + sal = ada_decode_exception_location (arg, &addr_string, &exp_string, + &cond_string, &cond, &ops); + create_ada_exception_breakpoint (sal, addr_string, exp_string, + cond_string, cond, ops, tempflag, + from_tty); +} + +/* Implement the "catch assert" command. */ + +static void +catch_assert_command (char *arg, int tempflag, int from_tty) +{ + struct symtab_and_line sal; + char *addr_string = NULL; + struct breakpoint_ops *ops = NULL; + + sal = ada_decode_assert_location (arg, &addr_string, &ops); + create_ada_exception_breakpoint (sal, addr_string, NULL, NULL, NULL, ops, + tempflag, from_tty); +} + /* Cover routine to allow wrapping target_enable_exception_catchpoints inside a catch_errors */ @@ -6524,6 +6725,15 @@ catch_command_1 (char *arg, int tempflag, int from_tty) { error (_("Catch of stop not yet implemented")); } + else if (strncmp (arg1_start, "exception", arg1_length) == 0) + { + catch_ada_exception_command (arg1_end + 1, tempflag, from_tty); + } + + else if (strncmp (arg1_start, "assert", arg1_length) == 0) + { + catch_assert_command (arg1_end + 1, tempflag, from_tty); + } /* This doesn't appear to be an event name */ @@ -6827,10 +7037,12 @@ delete_breakpoint (struct breakpoint *bpt) _("another breakpoint was inserted on top of " "a permanent breakpoint")); + memset (&b->loc->target_info, 0, sizeof (b->loc->target_info)); + b->loc->target_info.placed_address = b->loc->address; if (b->type == bp_hardware_breakpoint) - val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents); + val = target_insert_hw_breakpoint (&b->loc->target_info); else - val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents); + val = target_insert_breakpoint (&b->loc->target_info); /* If there was an error in the insert, print a message, then stop execution. */ if (val != 0) @@ -6943,7 +7155,10 @@ delete_command (char *arg, int from_tty) b->type != bp_thread_event && b->type != bp_overlay_event && b->number >= 0) - breaks_to_delete = 1; + { + breaks_to_delete = 1; + break; + } } /* Ask user only if there are some breakpoints to delete. */ @@ -7229,7 +7444,7 @@ breakpoint_re_set (void) set_language (save_language); input_radix = save_input_radix; - if (GET_LONGJMP_TARGET_P ()) + if (gdbarch_get_longjmp_target_p (current_gdbarch)) { create_longjmp_breakpoint ("longjmp"); create_longjmp_breakpoint ("_longjmp"); @@ -7510,7 +7725,7 @@ is valid is not currently in scope.\n"), bpt->number); int mem_cnt = can_use_hardware_watchpoint (bpt->val); /* Hack around 'unused var' error for some targets here */ - (void) mem_cnt, i; + (void) mem_cnt, (void) i; target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( bpt->type, i + mem_cnt, other_type_used); /* we can consider of type is bp_hardware_watchpoint, convert to @@ -7633,7 +7848,134 @@ decode_line_spec_1 (char *string, int funfirstline) error (_("Junk at end of line specification: %s"), string); return sals; } + +/* Create and insert a raw software breakpoint at PC. Return an + identifier, which should be used to remove the breakpoint later. + In general, places which call this should be using something on the + breakpoint chain instead; this function should be eliminated + someday. */ + +void * +deprecated_insert_raw_breakpoint (CORE_ADDR pc) +{ + struct bp_target_info *bp_tgt; + + bp_tgt = xmalloc (sizeof (struct bp_target_info)); + memset (bp_tgt, 0, sizeof (struct bp_target_info)); + + bp_tgt->placed_address = pc; + if (target_insert_breakpoint (bp_tgt) != 0) + { + /* Could not insert the breakpoint. */ + xfree (bp_tgt); + return NULL; + } + + return bp_tgt; +} + +/* Remove a breakpoint BP inserted by deprecated_insert_raw_breakpoint. */ + +int +deprecated_remove_raw_breakpoint (void *bp) +{ + struct bp_target_info *bp_tgt = bp; + int ret; + + ret = target_remove_breakpoint (bp_tgt); + xfree (bp_tgt); + + return ret; +} + +/* One (or perhaps two) breakpoints used for software single stepping. */ + +static void *single_step_breakpoints[2]; + +/* Create and insert a breakpoint for software single step. */ + +void +insert_single_step_breakpoint (CORE_ADDR next_pc) +{ + void **bpt_p; + + if (single_step_breakpoints[0] == NULL) + bpt_p = &single_step_breakpoints[0]; + else + { + gdb_assert (single_step_breakpoints[1] == NULL); + bpt_p = &single_step_breakpoints[1]; + } + + /* NOTE drow/2006-04-11: A future improvement to this function would be + to only create the breakpoints once, and actually put them on the + breakpoint chain. That would let us use set_raw_breakpoint. We could + adjust the addresses each time they were needed. Doing this requires + corresponding changes elsewhere where single step breakpoints are + handled, however. So, for now, we use this. */ + + *bpt_p = deprecated_insert_raw_breakpoint (next_pc); + if (*bpt_p == NULL) + error (_("Could not insert single-step breakpoint at 0x%s"), + paddr_nz (next_pc)); +} + +/* Remove and delete any breakpoints used for software single step. */ + +void +remove_single_step_breakpoints (void) +{ + gdb_assert (single_step_breakpoints[0] != NULL); + + /* See insert_single_step_breakpoint for more about this deprecated + call. */ + deprecated_remove_raw_breakpoint (single_step_breakpoints[0]); + single_step_breakpoints[0] = NULL; + + if (single_step_breakpoints[1] != NULL) + { + deprecated_remove_raw_breakpoint (single_step_breakpoints[1]); + single_step_breakpoints[1] = NULL; + } +} + +/* Check whether a software single-step breakpoint is inserted at PC. */ + +static int +single_step_breakpoint_inserted_here_p (CORE_ADDR pc) +{ + int i; + + for (i = 0; i < 2; i++) + { + struct bp_target_info *bp_tgt = single_step_breakpoints[i]; + if (bp_tgt && bp_tgt->placed_address == pc) + return 1; + } + + return 0; +} + +/* This help string is used for the break, hbreak, tbreak and thbreak commands. + It is defined as a macro to prevent duplication. + COMMAND should be a string constant containing the name of the command. */ +#define BREAK_ARGS_HELP(command) \ +command" [LOCATION] [thread THREADNUM] [if CONDITION]\n\ +LOCATION may be a line number, function name, or \"*\" and an address.\n\ +If a line number is specified, break at start of code for that line.\n\ +If a function is specified, break at start of code for that function.\n\ +If an address is specified, break at that exact address.\n\ +With no LOCATION, uses current execution address of selected stack frame.\n\ +This is useful for breaking on return to a stack frame.\n\ +\n\ +THREADNUM is the number from \"info threads\".\n\ +CONDITION is a boolean expression.\n\ +\n\ +Multiple breakpoints at one place are permitted, and useful if conditional.\n\ +\n\ +Do \"help breakpoints\" for info on other commands dealing with breakpoints." + void _initialize_breakpoint (void) { @@ -7669,22 +8011,28 @@ Usage is `condition N COND', where N is an integer and COND is an\n\ expression to be evaluated whenever breakpoint N is reached.")); c = add_com ("tbreak", class_breakpoint, tbreak_command, _("\ -Set a temporary breakpoint. Args like \"break\" command.\n\ +Set a temporary breakpoint.\n\ Like \"break\" except the breakpoint is only temporary,\n\ so it will be deleted when hit. Equivalent to \"break\" followed\n\ -by using \"enable delete\" on the breakpoint number.")); +by using \"enable delete\" on the breakpoint number.\n\ +\n" +BREAK_ARGS_HELP ("tbreak"))); set_cmd_completer (c, location_completer); c = add_com ("hbreak", class_breakpoint, hbreak_command, _("\ -Set a hardware assisted breakpoint. Args like \"break\" command.\n\ +Set a hardware assisted breakpoint.\n\ Like \"break\" except the breakpoint requires hardware support,\n\ -some target hardware may not have this support.")); +some target hardware may not have this support.\n\ +\n" +BREAK_ARGS_HELP ("hbreak"))); set_cmd_completer (c, location_completer); c = add_com ("thbreak", class_breakpoint, thbreak_command, _("\ -Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\ +Set a temporary hardware assisted breakpoint.\n\ Like \"hbreak\" except the breakpoint is only temporary,\n\ -so it will be deleted when hit.")); +so it will be deleted when hit.\n\ +\n" +BREAK_ARGS_HELP ("thbreak"))); set_cmd_completer (c, location_completer); add_prefix_cmd ("enable", class_breakpoint, enable_command, _("\ @@ -7763,6 +8111,7 @@ Also a prefix command for deletion of other GDB objects.\n\ The \"unset\" command is also an alias for \"delete\"."), &deletelist, "delete ", 1, &cmdlist); add_com_alias ("d", "delete", class_breakpoint, 1); + add_com_alias ("del", "delete", class_breakpoint, 1); if (xdb_commands) add_com ("db", class_breakpoint, delete_command, _("\ Delete some breakpoints.\n\ @@ -7789,17 +8138,8 @@ is executing in.\n\ See also the \"delete\" command which clears breakpoints by number.")); c = add_com ("break", class_breakpoint, break_command, _("\ -Set breakpoint at specified line or function.\n\ -Argument may be line number, function name, or \"*\" and an address.\n\ -If line number is specified, break at start of code for that line.\n\ -If function is specified, break at start of code for that function.\n\ -If an address is specified, break at that exact address.\n\ -With no arg, uses current execution address of selected stack frame.\n\ -This is useful for breaking on return to a stack frame.\n\ -\n\ -Multiple breakpoints at one place are permitted, and useful if conditional.\n\ -\n\ -Do \"help breakpoints\" for info on other commands dealing with breakpoints.")); +Set breakpoint at specified line or function.\n" +BREAK_ARGS_HELP ("break"))); set_cmd_completer (c, location_completer); add_com_alias ("b", "break", class_run, 1); @@ -7920,6 +8260,11 @@ The act of your program's execution stopping may also be caught:\n\ C++ exceptions may be caught:\n\ \tcatch throw - all exceptions, when thrown\n\ \tcatch catch - all exceptions, when caught\n\ +Ada exceptions may be caught:\n\ +\tcatch exception - all exceptions, when raised\n\ +\tcatch exception - a particular exception, when raised\n\ +\tcatch exception unhandled - all unhandled exceptions, when raised\n\ +\tcatch assert - all failed assertions, when raised\n\ \n\ Do \"help set follow-fork-mode\" for info on debugging your program\n\ after a fork or vfork is caught.\n\n\ @@ -7997,4 +8342,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; }