#define BREAKPOINT_MAX 16
\f
-/* The follow stuff is an abstract data type "bpstat" ("breakpoint status").
+/* Type of breakpoint. */
+/* FIXME In the future, we should fold all other breakpoint-like things into
+ here. This includes:
+
+ * call-dummy (the breakpoint at the end of a subroutine stub that gdb
+ uses to call functions in the target) (definately).
+
+ * single-step (for machines where we have to simulate single stepping)
+ (probably, though perhaps it is better for it to look as much as
+ possible like a single-step to wait_for_inferior). */
+
+enum bptype {
+ bp_breakpoint, /* Normal breakpoint */
+ bp_until, /* used by until command */
+ bp_finish, /* used by finish command */
+ bp_watchpoint, /* Watchpoint */
+ bp_longjmp, /* secret breakpoint to find longjmp() */
+ bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
+
+ /* Used by wait_for_inferior for stepping over subroutine calls, for
+ stepping over signal handlers, and for skipping prologues. */
+ bp_step_resume,
+
+ /* The breakpoint at the end of a call dummy. */
+ bp_call_dummy
+};
+
+/* States of enablement of breakpoint. */
+
+enum enable { disabled, enabled};
+
+/* Disposition of breakpoint. Ie: what to do after hitting it. */
+
+enum bpdisp {
+ delete, /* Delete it */
+ disable, /* Disable it */
+ donttouch /* Leave it alone */
+};
+
+/* Note that the ->silent field is not currently used by any commands
+ (though the code is in there if it was to be, and set_raw_breakpoint
+ does set it to 0). I implemented it because I thought it would be
+ useful for a hack I had to put in; I'm going to leave it in because
+ I can see how there might be times when it would indeed be useful */
+
+/* This is for a breakpoint or a watchpoint. */
+
+struct breakpoint
+{
+ struct breakpoint *next;
+ /* Type of breakpoint. */
+ enum bptype type;
+ /* Zero means disabled; remember the info but don't break here. */
+ enum enable enable;
+ /* What to do with this breakpoint after we hit it. */
+ enum bpdisp disposition;
+ /* Number assigned to distinguish breakpoints. */
+ int number;
+
+ /* Address to break at, or NULL if not a breakpoint. */
+ CORE_ADDR address;
+
+ /* Line number of this address. Only matters if address is
+ non-NULL. */
+
+ int line_number;
+
+ /* Source file name of this address. Only matters if address is
+ non-NULL. */
+
+ char *source_file;
+
+ /* Non-zero means a silent breakpoint (don't print frame info
+ if we stop here). */
+ unsigned char silent;
+ /* Number of stops at this breakpoint that should
+ be continued automatically before really stopping. */
+ int ignore_count;
+ /* "Real" contents of byte where breakpoint has been inserted.
+ Valid only when breakpoints are in the program. Under the complete
+ control of the target insert_breakpoint and remove_breakpoint routines.
+ No other code should assume anything about the value(s) here. */
+ char shadow_contents[BREAKPOINT_MAX];
+ /* Nonzero if this breakpoint is now inserted. Only matters if address
+ is non-NULL. */
+ char inserted;
+ /* Nonzero if this is not the first breakpoint in the list
+ for the given address. Only matters if address is non-NULL. */
+ char duplicate;
+ /* Chain of command lines to execute when this breakpoint is hit. */
+ struct command_line *commands;
+ /* Stack depth (address of frame). If nonzero, break only if fp
+ equals this. */
+ FRAME_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;
+ /* String form of the breakpoint condition (malloc'd), or NULL if there
+ is no condition. */
+ char *cond_string;
+ /* String form of exp (malloc'd), or NULL if none. */
+ char *exp_string;
+
+ /* The expression we are watching, or NULL if not a watchpoint. */
+ struct expression *exp;
+ /* The largest block within which it is valid, or NULL if it is
+ 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;
+};
+\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. */
breakpoint (if we hit a breakpoint). */
/* FIXME: prototypes uses equivalence between FRAME_ADDR and CORE_ADDR */
extern bpstat bpstat_stop_status PARAMS ((CORE_ADDR *, CORE_ADDR));
+\f
+/* This bpstat_what stuff tells wait_for_inferior what to do with a
+ breakpoint (a challenging task). */
-/* Return values from bpstat_what. */
-enum bpstat_what {
+enum bpstat_what_main_action {
/* Perform various other tests; that is, this bpstat does not
say to perform any action (e.g. failed watchpoint and nothing
else). */
BPSTAT_WHAT_STOP_NOISY,
/* Remove breakpoints, single step once, then put them back in and
- go back to what we were doing. */
+ go back to what we were doing. It's possible that this should be
+ removed from the main_action and put into a separate field, to more
+ cleanly handle BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE. */
BPSTAT_WHAT_SINGLE,
/* Set longjmp_resume breakpoint, remove all other breakpoints,
BPSTAT_WHAT_LAST
};
-/* Tell what to do about this bpstat. */
-enum bpstat_what bpstat_what PARAMS ((bpstat));
+struct bpstat_what {
+ enum bpstat_what_main_action main_action : 4;
+
+ /* Did we hit the step resume breakpoint? This is separate from the
+ main_action to allow for it to be combined with any of the main
+ actions. */
+ unsigned int step_resume : 1;
+
+ /* Did we hit a call dummy breakpoint? This only goes with a main_action
+ of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
+ continuing from a call dummy without popping the frame is not a
+ useful one). */
+ unsigned int call_dummy : 1;
+};
+/* Tell what to do about this bpstat. */
+struct bpstat_what bpstat_what PARAMS ((bpstat));
+\f
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *));
Return 0 if passed a bpstat which does not indicate any breakpoints. */
extern int bpstat_num PARAMS ((bpstat *));
-/* Perform actions associated with having stopped at *BSP. */
+/* Perform actions associated with having stopped at *BSP. Actually, we just
+ use this for breakpoint commands. Perhaps other actions will go here
+ later, but this is executed at a late time (from the command loop). */
extern void bpstat_do_actions PARAMS ((bpstat *));
/* Modify BS so that the actions will not be performed. */
int (*print_it) PARAMS((bpstat bs));
};
\f
-/* Type of breakpoint. */
-/* FIXME In the future, we should fold all other breakpoint-like things into
- here. This includes:
-
- 1) single-step (for machines where we have to simulate single stepping),
- 2) step-resume (for 'next'ing over subroutine calls),
- 3) call-dummy (the breakpoint at the end of a subroutine stub that gdb
- uses to call functions in the target).
-
- I definately agree with (2) and (3); I'm not as sure about (1)
- (it is a low-level thing, perhaps the best thing is that it looks
- as much as possible like a single-step to wait_for_inferior)
- -kingdon, 8 Apr 93.
-*/
-
-enum bptype {
- bp_breakpoint, /* Normal breakpoint */
- bp_until, /* used by until command */
- bp_finish, /* used by finish command */
- bp_watchpoint, /* Watchpoint */
- bp_longjmp, /* secret breakpoint to find longjmp() */
- bp_longjmp_resume /* secret breakpoint to escape longjmp() */
-};
-
-/* States of enablement of breakpoint. */
-
-enum enable { disabled, enabled};
-
-/* Disposition of breakpoint. Ie: what to do after hitting it. */
-
-enum bpdisp {
- delete, /* Delete it */
- disable, /* Disable it */
- donttouch /* Leave it alone */
-};
-
-/* Note that the ->silent field is not currently used by any commands
- (though the code is in there if it was to be, and set_raw_breakpoint
- does set it to 0). I implemented it because I thought it would be
- useful for a hack I had to put in; I'm going to leave it in because
- I can see how there might be times when it would indeed be useful */
-
-/* This is for a breakpoint or a watchpoint. */
-
-struct breakpoint
-{
- struct breakpoint *next;
- /* Type of breakpoint. */
- enum bptype type;
- /* Zero means disabled; remember the info but don't break here. */
- enum enable enable;
- /* What to do with this breakpoint after we hit it. */
- enum bpdisp disposition;
- /* Number assigned to distinguish breakpoints. */
- int number;
- /* Address to break at, or NULL if not a breakpoint. */
- CORE_ADDR address;
- /* Line number of this address. Redundant. Only matters if address
- is non-NULL. */
- int line_number;
- /* Symtab of file of this address. Redundant. Only matters if address
- is non-NULL. */
- struct symtab *symtab;
- /* Non-zero means a silent breakpoint (don't print frame info
- if we stop here). */
- unsigned char silent;
- /* Number of stops at this breakpoint that should
- be continued automatically before really stopping. */
- int ignore_count;
- /* "Real" contents of byte where breakpoint has been inserted.
- Valid only when breakpoints are in the program. Under the complete
- control of the target insert_breakpoint and remove_breakpoint routines.
- No other code should assume anything about the value(s) here. */
- char shadow_contents[BREAKPOINT_MAX];
- /* Nonzero if this breakpoint is now inserted. Only matters if address
- is non-NULL. */
- char inserted;
- /* Nonzero if this is not the first breakpoint in the list
- for the given address. Only matters if address is non-NULL. */
- char duplicate;
- /* Chain of command lines to execute when this breakpoint is hit. */
- struct command_line *commands;
- /* Stack depth (address of frame). If nonzero, break only if fp
- equals this. */
- FRAME_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;
- /* String form of the breakpoint condition (malloc'd), or NULL if there
- is no condition. */
- char *cond_string;
- /* String form of exp (malloc'd), or NULL if none. */
- char *exp_string;
-
- /* The expression we are watching, or NULL if not a watchpoint. */
- struct expression *exp;
- /* The largest block within which it is valid, or NULL if it is
- 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;
-};
-\f
/* Prototypes for breakpoint-related functions. */
#ifdef __STDC__ /* Forward declarations for prototypes */