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)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ {
+ b->related_breakpoint->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
+ }
+ b->enable = disable;
+ b->disposition = del_at_next_stop;
}
/* Restore the frame and level. */
{
b->inserted = 0;
- /* If the call dummy breakpoint is at the entry point it will
- cause problems when the inferior is rerun, so we better
- get rid of it. */
- if (b->type == bp_call_dummy)
- delete_breakpoint (b);
+ switch (b->type)
+ {
+ case bp_call_dummy:
+ case bp_watchpoint_scope:
- /* Likewise for scope breakpoints. */
- if (b->type == bp_watchpoint_scope)
- delete_breakpoint (b);
+ /* If the call dummy breakpoint is at the entry point it will
+ cause problems when the inferior is rerun, so we better
+ get rid of it.
- /* Likewise for watchpoints on local expressions. */
- if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint ||
- b->type == bp_read_watchpoint || b->type == bp_access_watchpoint)
- && b->exp_valid_block != NULL)
- delete_breakpoint (b);
+ Also get rid of scope breakpoints. */
+ delete_breakpoint (b);
+ break;
+
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ case bp_read_watchpoint:
+ case bp_access_watchpoint:
+
+ /* Likewise for watchpoints on local expressions. */
+ if (b->exp_valid_block != NULL)
+ delete_breakpoint (b);
+ break;
+
+ default:
+ break;
+ }
}
}
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)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ {
+ b->related_breakpoint->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
+ }
+ b->enable = disable;
+ b->disposition = del_at_next_stop;
return WP_DELETED;
}
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ {
+ b->related_breakpoint->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
+ }
+ b->enable = disable;
+ b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
case 0:
/* Error from catch_errors. */
printf_filtered ("Watchpoint %d deleted.\n", b->number);
- if (b->related_breakpoint)
- delete_breakpoint (b->related_breakpoint);
- delete_breakpoint (b);
+ if (b->related_breakpoint)
+ {
+ b->related_breakpoint->enable = disable;
+ b->related_breakpoint->disposition = del_at_next_stop;
+ }
+ b->enable = disable;
+ b->disposition = del_at_next_stop;
/* We've already printed what needs to be printed. */
bs->print_it = print_it_done;
break;
"sigtramp",
"watchpoint scope", "call dummy",
"shlib events" };
- static char *bpdisps[] = {"del", "dis", "keep"};
+ static char *bpdisps[] = {"del", "dstp", "dis", "keep"};
static char bpenables[] = "ny";
char wrap_indent[80];
free ((PTR)sals.sals);
}
\f
-/* Delete breakpoint in BS if they are `delete' breakpoints.
+/* Delete breakpoint in BS if they are `delete' breakpoints and
+ all breakpoints that are marked for deletion, whether hit or not.
This is called after any breakpoint is hit, or after errors. */
void
breakpoint_auto_delete (bs)
bpstat bs;
{
+ struct breakpoint *b, *temp;
+
for (; bs; bs = bs->next)
if (bs->breakpoint_at && bs->breakpoint_at->disposition == del
&& bs->stop)
delete_breakpoint (bs->breakpoint_at);
+
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ {
+ if (b->disposition == del_at_next_stop)
+ delete_breakpoint (b);
+ }
}
/* Delete a breakpoint and clean up all traces of it in the data structures. */
/* Data structures associated with breakpoints in GDB.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if !defined (BREAKPOINT_H)
#define BREAKPOINT_H 1
enum bptype {
bp_breakpoint, /* Normal breakpoint */
+ bp_hardware_breakpoint, /* Hardware assisted breakpoint */
bp_until, /* used by until command */
bp_finish, /* used by finish command */
bp_watchpoint, /* Watchpoint */
+ bp_hardware_watchpoint, /* Hardware assisted watchpoint */
+ bp_read_watchpoint, /* read watchpoint, (hardware assisted) */
+ bp_access_watchpoint, /* access watchpoint, (hardware assisted) */
bp_longjmp, /* secret breakpoint to find longjmp() */
bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
/* Used by wait_for_inferior for stepping over signal handlers. */
bp_through_sigtramp,
+ /* Used to detect when a watchpoint expression has gone out of
+ scope. These breakpoints are usually not visible to the user.
+
+ This breakpoint has some interesting properties:
+
+ 1) There's always a 1:1 mapping between watchpoints
+ on local variables and watchpoint_scope breakpoints.
+
+ 2) It automatically deletes itself and the watchpoint it's
+ associated with when hit.
+
+ 3) It can never be disabled. */
+ bp_watchpoint_scope,
+
/* The breakpoint at the end of a call dummy. */
/* FIXME: What if the function we are calling longjmp()s out of the
call, or the user gets out with the "return" command? We currently
(Probably can solve this by noticing longjmp, "return", etc., it's
similar to noticing when a watchpoint on a local variable goes out
of scope (with hardware support for watchpoints)). */
- bp_call_dummy
+ bp_call_dummy,
+
+ /* Some dynamic linkers (HP, maybe Solaris) can arrange for special
+ code in the inferior to run when significant events occur in the
+ dynamic linker (for example a library is loaded or unloaded).
+
+ By placing a breakpoint in this magic code GDB will get control
+ when these significant events occur. GDB can then re-examine
+ the dynamic linker's data structures to discover any newly loaded
+ dynamic libraries. */
+ bp_shlib_event
};
/* States of enablement of breakpoint. */
-enum enable { disabled, enabled};
+enum enable { disabled, enabled, shlib_disabled};
/* Disposition of breakpoint. Ie: what to do after hitting it. */
enum bpdisp {
- delete, /* Delete it */
+ del, /* Delete it */
+ del_at_next_stop, /* Delete at next stop, whether hit or not */
disable, /* Disable it */
donttouch /* Leave it alone */
};
struct command_line *commands;
/* Stack depth (address of frame). If nonzero, break only if fp
equals this. */
- FRAME_ADDR frame;
+ CORE_ADDR frame;
/* Conditional. Break only if this expression's value is nonzero. */
struct expression *cond;
/* String we used to set the breakpoint (malloc'd). Only matters if
address is non-NULL. */
char *addr_string;
+ /* Language we used to set the breakpoint. */
+ enum language language;
+ /* Input radix we used to set the breakpoint. */
+ int input_radix;
/* String form of the breakpoint condition (malloc'd), or NULL if there
is no condition. */
char *cond_string;
valid anywhere (e.g. consists just of global symbols). */
struct block *exp_valid_block;
/* Value of the watchpoint the last time we checked it. */
- value val;
+ value_ptr val;
+
+ /* Holds the value chain for a hardware watchpoint expression. */
+ value_ptr val_chain;
+
+ /* Holds the address of the related watchpoint_scope breakpoint
+ when using watchpoints on local variables (might the concept
+ of a related breakpoint be useful elsewhere, if not just call
+ it the watchpoint_scope breakpoint or something like that. FIXME). */
+ struct breakpoint *related_breakpoint;
+
+ /* Holds the frame address which identifies the frame this watchpoint
+ should be evaluated in, or NULL if the watchpoint should be evaluated
+ on the outermost frame. */
+ CORE_ADDR watchpoint_frame;
+
/* Thread number for thread-specific breakpoint, or -1 if don't care */
int thread;
+
+ /* Count of the number of times this breakpoint was taken, dumped
+ with the info, but not used for anything else. Useful for
+ seeing how many times you hit a break prior to the program
+ aborting, so you can back up to just before the abort. */
+ int hit_count;
+
};
\f
/* The following stuff is an abstract data type "bpstat" ("breakpoint status").
This provides the ability to determine whether we have stopped at a
breakpoint, and what we should do about it. */
-typedef struct bpstat *bpstat;
+typedef struct bpstats *bpstat;
/* Interface: */
/* Clear a bpstat so that it says we are not at any breakpoint.
is part of the bpstat is copied as well. */
extern bpstat bpstat_copy PARAMS ((bpstat));
-/* FIXME: prototypes uses equivalence between FRAME_ADDR and CORE_ADDR */
-extern bpstat bpstat_stop_status PARAMS ((CORE_ADDR *, CORE_ADDR, int));
+extern bpstat bpstat_stop_status PARAMS ((CORE_ADDR *, int));
\f
/* This bpstat_what stuff tells wait_for_inferior what to do with a
breakpoint (a challenging task). */
checking. */
BPSTAT_WHAT_THROUGH_SIGTRAMP,
+ /* Check the dynamic linker's data structures for new libraries, then
+ keep checking. */
+ BPSTAT_WHAT_CHECK_SHLIBS,
+
/* This is just used to keep track of how many enums there are. */
BPSTAT_WHAT_LAST
};
extern void bpstat_clear_actions PARAMS ((bpstat));
/* Implementation: */
-struct bpstat
+struct bpstats
{
/* Linked list because there can be two breakpoints at the
same place, and a bpstat reflects the fact that both have been hit. */
/* Commands left to be done. */
struct command_line *commands;
/* Old value associated with a watchpoint. */
- value old_val;
+ value_ptr old_val;
/* Nonzero if this breakpoint tells us to print the frame. */
char print;
extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int));
-extern void
-until_break_command PARAMS ((char *, int));
+extern void until_break_command PARAMS ((char *, int));
-extern void
-breakpoint_re_set PARAMS ((void));
+extern void breakpoint_re_set PARAMS ((void));
-extern void
-clear_momentary_breakpoints PARAMS ((void));
+extern void clear_momentary_breakpoints PARAMS ((void));
-/* FIXME: Prototype uses equivalence of "struct frame_info *" and FRAME */
-extern struct breakpoint *
-set_momentary_breakpoint PARAMS ((struct symtab_and_line,
- struct frame_info *,
- enum bptype));
+extern struct breakpoint *set_momentary_breakpoint
+ PARAMS ((struct symtab_and_line, struct frame_info *, enum bptype));
-extern void
-set_ignore_count PARAMS ((int, int, int));
+extern void set_ignore_count PARAMS ((int, int, int));
-extern void
-set_default_breakpoint PARAMS ((int, CORE_ADDR, struct symtab *, int));
+extern void set_default_breakpoint PARAMS ((int, CORE_ADDR, struct symtab *, int));
-extern void
-mark_breakpoints_out PARAMS ((void));
+extern void mark_breakpoints_out PARAMS ((void));
-extern void
-breakpoint_init_inferior PARAMS ((void));
+extern void breakpoint_init_inferior PARAMS ((void));
-extern void
-delete_breakpoint PARAMS ((struct breakpoint *));
+extern void delete_breakpoint PARAMS ((struct breakpoint *));
-extern void
-breakpoint_auto_delete PARAMS ((bpstat));
+extern void breakpoint_auto_delete PARAMS ((bpstat));
-extern void
-breakpoint_clear_ignore_counts PARAMS ((void));
+extern void breakpoint_clear_ignore_counts PARAMS ((void));
-extern void
-break_command PARAMS ((char *, int));
+extern void break_command PARAMS ((char *, int));
-extern int
-insert_breakpoints PARAMS ((void));
+extern int insert_breakpoints PARAMS ((void));
-extern int
-remove_breakpoints PARAMS ((void));
+extern int remove_breakpoints PARAMS ((void));
-extern void
-enable_longjmp_breakpoint PARAMS ((void));
+extern void enable_longjmp_breakpoint PARAMS ((void));
-extern void
-disable_longjmp_breakpoint PARAMS ((void));
+extern void disable_longjmp_breakpoint PARAMS ((void));
-extern void
-set_longjmp_resume_breakpoint PARAMS ((CORE_ADDR, FRAME));
+extern void set_longjmp_resume_breakpoint PARAMS ((CORE_ADDR,
+ struct frame_info *));
+extern void clear_breakpoint_hit_counts PARAMS ((void));
+
/* The following are for displays, which aren't really breakpoints, but
here is as good a place as any for them. */
-extern void
-disable_current_display PARAMS ((void));
+extern void disable_current_display PARAMS ((void));
+
+extern void do_displays PARAMS ((void));
+
+extern void disable_display PARAMS ((int));
+
+extern void clear_displays PARAMS ((void));
+
+extern void disable_breakpoint PARAMS ((struct breakpoint *));
+
+extern void enable_breakpoint PARAMS ((struct breakpoint *));
-extern void
-do_displays PARAMS ((void));
+extern void create_solib_event_breakpoint PARAMS ((CORE_ADDR));
-extern void
-disable_display PARAMS ((int));
+extern void remove_solib_event_breakpoints PARAMS ((void));
-extern void
-clear_displays PARAMS ((void));
+extern void re_enable_breakpoints_in_shlibs PARAMS ((void));
#endif /* !defined (BREAKPOINT_H) */