/* Everything about breakpoints, for GDB.
- Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
#include "value.h"
#include "command.h"
#include "inferior.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "target.h"
#include "language.h"
#include "gdb_string.h"
#include "demangle.h"
#include "annotate.h"
+#include "symfile.h"
+#include "objfiles.h"
-/* local function prototypes */
+/* Prototypes for local functions. */
-static void
-catch_command_1 PARAMS ((char *, int, int));
+static void catch_command_1 PARAMS ((char *, int, int));
-static void
-enable_delete_command PARAMS ((char *, int));
+static void enable_delete_command PARAMS ((char *, int));
-static void
-enable_delete_breakpoint PARAMS ((struct breakpoint *));
+static void enable_delete_breakpoint PARAMS ((struct breakpoint *));
-static void
-enable_once_command PARAMS ((char *, int));
+static void enable_once_command PARAMS ((char *, int));
-static void
-enable_once_breakpoint PARAMS ((struct breakpoint *));
+static void enable_once_breakpoint PARAMS ((struct breakpoint *));
-static void
-disable_command PARAMS ((char *, int));
+static void disable_command PARAMS ((char *, int));
-static void
-enable_command PARAMS ((char *, int));
+static void enable_command PARAMS ((char *, int));
-static void
-map_breakpoint_numbers PARAMS ((char *, void (*)(struct breakpoint *)));
+static void map_breakpoint_numbers PARAMS ((char *,
+ void (*)(struct breakpoint *)));
-static void
-ignore_command PARAMS ((char *, int));
+static void ignore_command PARAMS ((char *, int));
-static int
-breakpoint_re_set_one PARAMS ((char *));
+static int breakpoint_re_set_one PARAMS ((char *));
-static void
-delete_command PARAMS ((char *, int));
+static void clear_command PARAMS ((char *, int));
-static void
-clear_command PARAMS ((char *, int));
+static void catch_command PARAMS ((char *, int));
-static void
-catch_command PARAMS ((char *, int));
+static struct symtabs_and_lines get_catch_sals PARAMS ((int));
-static struct symtabs_and_lines
-get_catch_sals PARAMS ((int));
+static void watch_command PARAMS ((char *, int));
-static void
-watch_command PARAMS ((char *, int));
+static int can_use_hardware_watchpoint PARAMS ((struct value *));
-static int
-can_use_hardware_watchpoint PARAMS ((struct value *));
+static void tbreak_command PARAMS ((char *, int));
-static void
-tbreak_command PARAMS ((char *, int));
+static void break_command_1 PARAMS ((char *, int, int));
-static void
-break_command_1 PARAMS ((char *, int, int));
+static void mention PARAMS ((struct breakpoint *));
-static void
-mention PARAMS ((struct breakpoint *));
+struct breakpoint *set_raw_breakpoint PARAMS ((struct symtab_and_line));
-static struct breakpoint *
-set_raw_breakpoint PARAMS ((struct symtab_and_line));
+static void check_duplicates PARAMS ((CORE_ADDR, asection *));
-static void
-check_duplicates PARAMS ((CORE_ADDR));
+static void describe_other_breakpoints PARAMS ((CORE_ADDR, asection *));
-static void
-describe_other_breakpoints PARAMS ((CORE_ADDR));
+static void breakpoints_info PARAMS ((char *, int));
-static void
-breakpoints_info PARAMS ((char *, int));
+static void breakpoint_1 PARAMS ((int, int));
-static void
-breakpoint_1 PARAMS ((int, int));
+static bpstat bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
-static bpstat
-bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
+static int breakpoint_cond_eval PARAMS ((char *));
-static int
-breakpoint_cond_eval PARAMS ((char *));
+static void cleanup_executing_breakpoints PARAMS ((PTR));
-static void
-cleanup_executing_breakpoints PARAMS ((int));
+static void commands_command PARAMS ((char *, int));
-static void
-commands_command PARAMS ((char *, int));
+static void condition_command PARAMS ((char *, int));
-static void
-condition_command PARAMS ((char *, int));
+static int get_number PARAMS ((char **));
-static int
-get_number PARAMS ((char **));
+static int remove_breakpoint PARAMS ((struct breakpoint *));
-static void
-set_breakpoint_count PARAMS ((int));
+static int print_it_normal PARAMS ((bpstat));
-static int
-remove_breakpoint PARAMS ((struct breakpoint *));
+static int watchpoint_check PARAMS ((char *));
+
+static int print_it_done PARAMS ((bpstat));
+
+static int print_it_noop PARAMS ((bpstat));
+
+static void maintenance_info_breakpoints PARAMS ((char *, int));
+
+#ifdef GET_LONGJMP_TARGET
+static void create_longjmp_breakpoint PARAMS ((char *));
+#endif
+
+static int hw_breakpoint_used_count PARAMS ((void));
+
+static int hw_watchpoint_used_count PARAMS ((enum bptype, int *));
+
+static void hbreak_command PARAMS ((char *, int));
+
+static void thbreak_command PARAMS ((char *, int));
+
+static void watch_command_1 PARAMS ((char *, int, int));
+
+static void rwatch_command PARAMS ((char *, int));
+
+static void awatch_command PARAMS ((char *, int));
+
+static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+
+/* Prototypes for exported functions. */
+
+void delete_command PARAMS ((char *, int));
+
+void _initialize_breakpoint PARAMS ((void));
+
+void set_breakpoint_count PARAMS ((int));
extern int addressprint; /* Print machine addresses? */
+#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
+static int internal_breakpoint_number = -1;
+#endif
+
/* Are we executing breakpoint commands? */
static int executing_breakpoint_commands;
b? (tmp=b->next, 1): 0; \
b = tmp)
+/* True if SHIFT_INST_REGS defined, false otherwise. */
+
+int must_shift_inst_regs =
+#if defined(SHIFT_INST_REGS)
+1
+#else
+0
+#endif
+;
+
/* True if breakpoint hit counts should be displayed in breakpoint info. */
int show_breakpoint_hit_counts = 1;
/* Number of last breakpoint made. */
-static int breakpoint_count;
+int breakpoint_count;
/* Set breakpoint count to NUM. */
-static void
+void
set_breakpoint_count (num)
int num;
{
ALL_BREAKPOINTS (b)
if (b->number == bnum)
{
- if (from_tty && input_from_terminal_p ())
- printf_filtered ("Type commands for when breakpoint %d is hit, one per line.\n\
-End with a line saying just \"end\".\n", bnum);
- l = read_command_lines ();
+ char tmpbuf[128];
+ sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum);
+ l = read_command_lines (tmpbuf, from_tty);
free_command_lines (&b->commands);
b->commands = l;
breakpoints_changed ();
if (b->type == bp_hardware_breakpoint)
val = target_insert_hw_breakpoint(b->address, b->shadow_contents);
else
- val = target_insert_breakpoint(b->address, b->shadow_contents);
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should set the breakpoint at the LMA address.
+ Only if the section is currently mapped should we ALSO
+ set a break at the VMA address. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_insert_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_insert_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_insert_breakpoint(b->address, b->shadow_contents);
+ }
if (val)
{
/* Can't set the breakpoint. */
within_current_scope = 1;
else
{
- struct frame_info *fi =
- find_frame_addr_in_frame_chain (b->watchpoint_frame);
+ struct frame_info *fi;
+
+ /* There might be no current frame at this moment if we are
+ resuming from a step over a breakpoint.
+ Set up current frame before trying to find the watchpoint
+ frame. */
+ get_current_frame ();
+ fi = find_frame_addr_in_frame_chain (b->watchpoint_frame);
within_current_scope = (fi != NULL);
if (within_current_scope)
select_frame (fi, -1);
Hardware watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
}
if (b->type == bp_hardware_breakpoint)
val = target_remove_hw_breakpoint(b->address, b->shadow_contents);
else
- val = target_remove_breakpoint(b->address, b->shadow_contents);
+ {
+ /* Check to see if breakpoint is in an overlay section;
+ if so, we should remove the breakpoint at the LMA address.
+ If that is not equal to the raw address, then we should
+ presumable remove the breakpoint there as well. */
+ if (overlay_debugging && b->section &&
+ section_is_overlay (b->section))
+ {
+ CORE_ADDR addr;
+
+ addr = overlay_unmapped_address (b->address, b->section);
+ val = target_remove_breakpoint (addr, b->shadow_contents);
+ /* This would be the time to check val, to see if the
+ shadow breakpoint write to the load address succeeded.
+ However, this might be an ordinary occurrance, eg. if
+ the unmapped overlay is in ROM. */
+ val = 0; /* in case unmapped address failed */
+ if (section_is_mapped (b->section))
+ val = target_remove_breakpoint (b->address,
+ b->shadow_contents);
+ }
+ else /* ordinary (non-overlay) address */
+ val = target_remove_breakpoint(b->address, b->shadow_contents);
+ }
if (val)
return val;
b->inserted = 0;
at that address. */
if (v->lval == lval_memory)
{
- int addr, len;
+ int addr, len, type;
addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
len = TYPE_LENGTH (VALUE_TYPE (v));
- val = target_remove_watchpoint (addr, len, b->type);
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_remove_watchpoint (addr, len, type);
if (val == -1)
b->inserted = 1;
val = 0;
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
- if (b->enable != disabled
- && b->enable != shlib_disabled
- && b->address == pc)
- return 1;
+ if (b->enable == enabled
+ && b->address == pc) /* bp is enabled and matches pc */
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(), but it
+ only returns true if there is actually a breakpoint inserted at PC. */
+
+int
+breakpoint_inserted_here_p (pc)
+ CORE_ADDR pc;
+{
+ register struct breakpoint *b;
+
+ ALL_BREAKPOINTS (b)
+ if (b->inserted
+ && b->address == pc) /* bp is inserted and matches pc */
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
return 0;
}
frame_in_dummy (frame)
struct frame_info *frame;
{
+#ifdef CALL_DUMMY
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ return generic_pc_in_call_dummy (frame->pc, frame->frame);
+#else
struct breakpoint *b;
-#ifdef CALL_DUMMY
ALL_BREAKPOINTS (b)
{
- static unsigned LONGEST dummy[] = CALL_DUMMY;
+ static ULONGEST dummy[] = CALL_DUMMY;
if (b->type == bp_call_dummy
&& b->frame == frame->frame
&& frame->pc <= b->address)
return 1;
}
+#endif /* GENERIC_DUMMY_FRAMES */
#endif /* CALL_DUMMY */
return 0;
}
&& b->enable != shlib_disabled
&& b->address == pc
&& (b->thread == -1 || b->thread == thread))
- return 1;
+ {
+ if (overlay_debugging &&
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section))
+ continue; /* unmapped overlay -- can't be a match */
+ else
+ return 1;
+ }
return 0;
}
/* ARGSUSED */
static void
cleanup_executing_breakpoints (ignore)
- int ignore;
+ PTR ignore;
{
executing_breakpoint_commands = 0;
}
struct cleanup *old_chain;
struct command_line *cmd;
+ /* Avoid endless recursion if a `source' command is contained
+ in bs->commands. */
+ if (executing_breakpoint_commands)
+ return;
+
executing_breakpoint_commands = 1;
old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
Watchpoint %d deleted because the program has left the block in\n\
which its expression is valid.\n", bs->breakpoint_at->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
return WP_DELETED;
{
register struct breakpoint *b, *temp;
CORE_ADDR bp_addr;
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
/* True if we've hit a breakpoint (as opposed to a watchpoint). */
int real_breakpoint = 0;
-#endif
/* Root of the chain of bpstat's */
struct bpstats root_bs[1];
/* Pointer to the last thing in the chain currently. */
&& b->type != bp_hardware_watchpoint
&& b->type != bp_read_watchpoint
&& b->type != bp_access_watchpoint
- && b->type != bp_hardware_breakpoint
- && b->address != bp_addr)
- continue;
+ && b->type != bp_hardware_breakpoint) /* a non-watchpoint bp */
+ if (b->address != bp_addr || /* address doesn't match or */
+ (overlay_debugging && /* overlay doesn't match */
+ section_is_overlay (b->section) &&
+ !section_is_mapped (b->section)))
+ continue;
if (b->type == bp_hardware_breakpoint
&& b->address != (bp_addr - DECR_PC_AFTER_HW_BREAK))
/* Don't stop. */
bs->print_it = print_it_noop;
bs->stop = 0;
+ /* Don't consider this a hit. */
+ --(b->hit_count);
continue;
default:
/* Can't happen. */
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- {
- b->related_breakpoint->enable = disable;
- b->related_breakpoint->disposition = del_at_next_stop;
- }
- b->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
break;
}
}
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- else
+ else if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
real_breakpoint = 1;
-#endif
- if (b->frame && b->frame != (get_current_frame ())->frame)
+ if (b->frame && b->frame != (get_current_frame ())->frame &&
+ (b->type == bp_step_resume &&
+ (get_current_frame ())->frame INNER_THAN b->frame))
bs->stop = 0;
else
{
if (b->cond && value_is_zero)
{
bs->stop = 0;
+ /* Don't consider this a hit. */
+ --(b->hit_count);
}
else if (b->ignore_count > 0)
{
bs->next = NULL; /* Terminate the chain */
bs = root_bs->next; /* Re-grab the head of the chain */
-#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- if (bs)
+
+ if ((DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs) && bs)
{
if (real_breakpoint)
{
#endif /* No SHIFT_INST_REGS. */
}
}
-#endif /* DECR_PC_AFTER_BREAK != 0. */
/* The value of a hardware watchpoint hasn't changed, but the
intermediate memory locations we are watching may have. */
"watchpoint scope", "call dummy",
"shlib events" };
static char *bpdisps[] = {"del", "dstp", "dis", "keep"};
- static char bpenables[] = "ny";
+ static char bpenables[] = "nyn";
char wrap_indent[80];
ALL_BREAKPOINTS (b)
last_addr = b->address;
if (b->source_file)
{
- sym = find_pc_function (b->address);
+ sym = find_pc_sect_function (b->address, b->section);
if (sym)
{
fputs_filtered ("in ", gdb_stdout);
printf_filtered ("\n");
}
+ if (b->thread != -1)
+ {
+ /* FIXME should make an annotation for this */
+ printf_filtered ("\tstop only in thread %d\n", b->thread);
+ }
+
if (show_breakpoint_hit_counts && b->hit_count)
{
/* FIXME should make an annotation for this */
/* Print a message describing any breakpoints set at PC. */
static void
-describe_other_breakpoints (pc)
- register CORE_ADDR pc;
+describe_other_breakpoints (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register int others = 0;
register struct breakpoint *b;
ALL_BREAKPOINTS (b)
if (b->address == pc)
- others++;
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ others++;
if (others > 0)
{
printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
ALL_BREAKPOINTS (b)
if (b->address == pc)
- {
- others--;
- printf_filtered
- ("%d%s%s ",
- b->number,
- ((b->enable == disabled || b->enable == shlib_disabled)
- ? " (disabled)" : ""),
- (others > 1) ? "," : ((others == 1) ? " and" : ""));
- }
+ if (overlay_debugging == 0 ||
+ b->section == section)
+ {
+ others--;
+ printf_filtered
+ ("%d%s%s ",
+ b->number,
+ ((b->enable == disabled || b->enable == shlib_disabled)
+ ? " (disabled)" : ""),
+ (others > 1) ? "," : ((others == 1) ? " and" : ""));
+ }
printf_filtered ("also set at pc ");
print_address_numeric (pc, 1, gdb_stdout);
printf_filtered (".\n");
This is so that the bpt instruction is only inserted once. */
static void
-check_duplicates (address)
+check_duplicates (address, section)
CORE_ADDR address;
+ asection *section;
{
register struct breakpoint *b;
register int count = 0;
ALL_BREAKPOINTS (b)
if (b->enable != disabled
&& b->enable != shlib_disabled
- && b->address == address)
+ && b->address == address
+ && (overlay_debugging == 0 || b->section == section))
{
count++;
b->duplicate = count > 1;
error(); otherwise it leaves a bogus breakpoint on the chain. Validate
your arguments BEFORE calling this routine! */
-static struct breakpoint *
+struct breakpoint *
set_raw_breakpoint (sal)
struct symtab_and_line sal;
{
else
b->source_file = savestring (sal.symtab->filename,
strlen (sal.symtab->filename));
+ b->section = sal.section;
b->language = current_language->la_language;
b->input_radix = input_radix;
b->thread = -1;
b1->next = b;
}
- check_duplicates (sal.pc);
+ check_duplicates (sal.pc, sal.section);
breakpoints_changed ();
return b;
}
-static int internal_breakpoint_number = -1;
-
#ifdef GET_LONGJMP_TARGET
static void
struct symtab_and_line sal;
struct breakpoint *b;
+ INIT_SAL (&sal); /* initialize to zeroes */
if (func_name != NULL)
{
struct minimal_symbol *m;
else
return;
}
- else
- sal.pc = 0;
-
- sal.symtab = NULL;
- sal.line = 0;
-
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
if (!b) return;
if (b->type == bp_longjmp)
{
b->enable = enabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
|| b->type == bp_longjmp_resume)
{
b->enable = disabled;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
}
}
struct breakpoint *b;
struct symtab_and_line sal;
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.pc = address;
- sal.symtab = NULL;
- sal.line = 0;
+ sal.section = find_pc_overlay (sal.pc);
b = set_raw_breakpoint (sal);
b->number = internal_breakpoint_number--;
b->disposition = donttouch;
#endif
-int
+static int
hw_breakpoint_used_count()
{
register struct breakpoint *b;
return i;
}
-int
+static int
hw_watchpoint_used_count(type, other_type_used)
enum bptype type;
int *other_type_used;
b->frame = frame->frame;
else
b->frame = 0;
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
return;
}
}
sals.sals = NULL;
sals.nelts = 0;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', use the default breakpoint. */
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
+ sal.section = find_pc_overlay (sal.pc);
sals.sals[0] = sal;
sals.nelts = 1;
}
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->enable = enabled;
b->disposition = tempflag ? del : donttouch;
-
mention (b);
}
{
CORE_ADDR pc;
- if (sal->pc == 0 && sal->symtab != 0)
+ if (sal->pc == 0 && sal->symtab != NULL)
{
- pc = find_line_pc (sal->symtab, sal->line);
- if (pc == 0)
+ if (!find_line_pc (sal->symtab, sal->line, &pc))
error ("No line %d in file \"%s\".",
sal->line, sal->symtab->filename);
sal->pc = pc;
}
+
+ if (sal->section == 0 && sal->symtab != NULL)
+ {
+ struct blockvector *bv;
+ struct block *b;
+ struct symbol *sym;
+ int index;
+
+ bv = blockvector_for_pc_sect (sal->pc, 0, &index, sal->symtab);
+ if (bv != NULL)
+ {
+ b = BLOCKVECTOR_BLOCK (bv, index);
+ sym = block_function (b);
+ if (sym != NULL)
+ {
+ fixup_symbol_section (sym, sal->symtab->objfile);
+ sal->section = SYMBOL_BFD_SECTION (sym);
+ }
+ else
+ {
+ /* It really is worthwhile to have the section, so we'll just
+ have to look harder. This case can be executed if we have
+ line numbers but no functions (as can happen in assembly
+ source). */
+
+ struct minimal_symbol *msym;
+
+ msym = lookup_minimal_symbol_by_pc (sal->pc);
+ if (msym)
+ sal->section = SYMBOL_BFD_SECTION (msym);
+ }
+ }
+ }
}
void
struct expression *exp;
struct block *exp_valid_block;
struct value *val, *mark;
- struct frame_info *frame, *prev_frame;
+ struct frame_info *frame;
+ struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
char *exp_end = NULL;
char *tok, *end_tok;
char *cond_start = NULL;
char *cond_end = NULL;
struct expression *cond = NULL;
- int i, other_type_used, target_resources_ok;
+ int i, other_type_used, target_resources_ok = 0;
enum bptype bp_type;
int mem_cnt = 0;
- sal.pc = 0;
- sal.symtab = NULL;
- sal.line = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* Parse arguments. */
innermost_block = NULL;
expression. */
if (innermost_block)
{
- struct breakpoint *scope_breakpoint;
- struct symtab_and_line scope_sal;
-
if (prev_frame)
{
- scope_sal.pc = get_frame_pc (prev_frame);
- scope_sal.symtab = NULL;
- scope_sal.line = 0;
-
+ struct breakpoint *scope_breakpoint;
+ struct symtab_and_line scope_sal;
+
+ INIT_SAL (&scope_sal); /* initialize to zeroes */
+ scope_sal.pc = get_frame_pc (prev_frame);
+ scope_sal.section = find_pc_overlay (scope_sal.pc);
+
scope_breakpoint = set_raw_breakpoint (scope_sal);
set_breakpoint_count (breakpoint_count + 1);
scope_breakpoint->number = breakpoint_count;
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
- old_chain = make_cleanup(delete_breakpoint, breakpoint);
+ old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
/* Keep within the current frame */
sal = find_pc_line (prev_frame->pc, 0);
sal.pc = prev_frame->pc;
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
- make_cleanup(delete_breakpoint, breakpoint);
+ make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
}
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
#if 0
if (function (p))
{
- struct sal_chain *next
- = (struct sal_chain *)alloca (sizeof (struct sal_chain));
+ struct sal_chain *next = (struct sal_chain *)
+ alloca (sizeof (struct sal_chain));
next->next = sal_chain;
next->sal = get_catch_sal (p);
sal_chain = next;
char *save_arg;
int i;
- sal.line = sal.pc = sal.end = 0;
- sal.symtab = 0;
+ INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', all active catch clauses
are breakpointed. */
sal = sals.sals[i];
if (from_tty)
- describe_other_breakpoints (sal.pc);
+ describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
struct breakpoint *
set_breakpoint_sal (sal)
-struct symtab_and_line sal;
+ struct symtab_and_line sal;
{
struct breakpoint *b;
b = set_raw_breakpoint (sal);
}
else
{
- sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line));
+ sals.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ INIT_SAL (&sal); /* initialize to zeroes */
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
- sal.pc = 0;
if (sal.symtab == 0)
error ("No source file specified.");
But if sal.pc is zero, clear all bpts on specified line. */
sal = sals.sals[i];
found = (struct breakpoint *) 0;
+
while (breakpoint_chain
&& (sal.pc
- ? breakpoint_chain->address == sal.pc
+ ? (breakpoint_chain->address == sal.pc &&
+ (overlay_debugging == 0 ||
+ breakpoint_chain->section == sal.section))
: (breakpoint_chain->source_file != NULL
&& sal.symtab != NULL
&& STREQ (breakpoint_chain->source_file,
&& b->next->type != bp_read_watchpoint
&& b->next->type != bp_access_watchpoint
&& (sal.pc
- ? b->next->address == sal.pc
+ ? (b->next->address == sal.pc &&
+ (overlay_debugging == 0 ||
+ b->next->section == sal.section))
: (b->next->source_file != NULL
&& sal.symtab != NULL
&& STREQ (b->next->source_file, sal.symtab->filename)
break;
}
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
/* If this breakpoint was inserted, and there is another breakpoint
at the same address, we need to insert the other breakpoint. */
if (bpt->inserted
{
ALL_BREAKPOINTS (b)
if (b->address == bpt->address
+ && b->section == bpt->section
&& !b->duplicate
&& b->enable != disabled
&& b->enable != shlib_disabled)
free ((PTR)bpt);
}
-static void
+void
delete_command (arg, from_tty)
char *arg;
int from_tty;
{
+ struct breakpoint *b, *temp;
if (arg == 0)
{
+ int breaks_to_delete = 0;
+
+ /* Delete all breakpoints if no argument.
+ Do not delete internal or call-dummy breakpoints, these
+ have to be deleted with an explicit breakpoint number argument. */
+ ALL_BREAKPOINTS (b)
+ {
+ if (b->type != bp_call_dummy && b->number >= 0)
+ breaks_to_delete = 1;
+ }
+
/* Ask user only if there are some breakpoints to delete. */
if (!from_tty
- || (breakpoint_chain && query ("Delete all breakpoints? ")))
+ || (breaks_to_delete && query ("Delete all breakpoints? ")))
{
- /* No arg; clear all breakpoints. */
- while (breakpoint_chain)
- delete_breakpoint (breakpoint_chain);
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->type != bp_call_dummy && b->number >= 0)
+ delete_breakpoint (b);
+ }
}
}
else
strlen (sals.sals[i].symtab->filename));
b->line_number = sals.sals[i].line;
b->address = sals.sals[i].pc;
-
- check_duplicates (b->address);
+ check_duplicates (b->address, b->section);
mention (b);
rather than once for every breakpoint. */
breakpoints_changed ();
}
+ b->section = sals.sals[i].section;
b->enable = save_enable; /* Restore it, this worked. */
}
free ((PTR)sals.sals);
create_longjmp_breakpoint ("longjmp");
create_longjmp_breakpoint ("_longjmp");
create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
create_longjmp_breakpoint (NULL);
#endif
bpt->enable = disabled;
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
if (modify_breakpoint_hook)
modify_breakpoint_hook (bpt);
bpt->enable = enabled;
bpt->disposition = disposition;
- check_duplicates (bpt->address);
+ check_duplicates (bpt->address, bpt->section);
breakpoints_changed ();
if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint ||
int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
int mem_cnt = can_use_hardware_watchpoint (bpt->val);
+ /* Hack around 'unused var' error for some targets here */
+ (void) mem_cnt, 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
enable_breakpoint (bpt)
struct breakpoint *bpt;
{
- do_enable_breakpoint (bpt, donttouch);
+ do_enable_breakpoint (bpt, bpt->disposition);
}
/* The enable command enables the specified breakpoints (or all defined
With a subcommand you can enable temporarily.",
&enablelist, "enable ", 1, &cmdlist);
+ add_com_alias ("en", "enable", class_breakpoint, 1);
+
add_abbrev_prefix_cmd ("breakpoints", class_breakpoint, enable_command,
"Enable some breakpoints.\n\
Give breakpoint numbers (separated by spaces) as arguments.\n\