mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-18 21:34:13 +08:00
* defs.h (make_cleanup): Change PTR to void * when inside PARAMS.
Some of the following is in #ifdef CALL_DUMMY_BREAKPOINT_OFFSET. * breakpoint.h (enum bptype): Add bp_call_dummy. (struct bpstat_what): Add call_dummy field. * infrun.c (wait_for_inferior): Deal with it. * breakpoint.c (bpstat_what): Deal with call dummy breakpoint. * infcmd.c (run_stack_dummy): Set the call dummy breakpoint. * config/sparc/tm-sparc.h: Define CALL_DUMMY_BREAKPOINT_OFFSET.
This commit is contained in:
@ -1,4 +1,14 @@
|
|||||||
Fri Sep 17 10:10:05 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
|
Sat Sep 18 10:13:18 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
|
||||||
|
|
||||||
|
* defs.h (make_cleanup): Change PTR to void * when inside PARAMS.
|
||||||
|
|
||||||
|
Some of the following is in #ifdef CALL_DUMMY_BREAKPOINT_OFFSET.
|
||||||
|
* breakpoint.h (enum bptype): Add bp_call_dummy.
|
||||||
|
(struct bpstat_what): Add call_dummy field.
|
||||||
|
* infrun.c (wait_for_inferior): Deal with it.
|
||||||
|
* breakpoint.c (bpstat_what): Deal with call dummy breakpoint.
|
||||||
|
* infcmd.c (run_stack_dummy): Set the call dummy breakpoint.
|
||||||
|
* config/sparc/tm-sparc.h: Define CALL_DUMMY_BREAKPOINT_OFFSET.
|
||||||
|
|
||||||
* remote-sim.h: New file.
|
* remote-sim.h: New file.
|
||||||
* remote-sim.c: Add remote debug feature. Rename stuff to distinguish
|
* remote-sim.c: Add remote debug feature. Rename stuff to distinguish
|
||||||
|
@ -1221,6 +1221,12 @@ bpstat_what (bs)
|
|||||||
#define err BPSTAT_WHAT_STOP_NOISY
|
#define err BPSTAT_WHAT_STOP_NOISY
|
||||||
|
|
||||||
/* Given an old action and a class, come up with a new action. */
|
/* Given an old action and a class, come up with a new action. */
|
||||||
|
/* One interesting property of this table is that wp_silent is the same
|
||||||
|
as bp_silent and wp_noisy is the same as bp_noisy. That is because
|
||||||
|
after stopping, the check for whether to step over a breakpoint
|
||||||
|
(BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
|
||||||
|
reference to how we stopped. We retain separate wp_silent and bp_silent
|
||||||
|
codes in case we want to change that someday. */
|
||||||
static const enum bpstat_what_main_action
|
static const enum bpstat_what_main_action
|
||||||
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
|
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
|
||||||
{
|
{
|
||||||
@ -1245,7 +1251,7 @@ bpstat_what (bs)
|
|||||||
#undef clrlrs
|
#undef clrlrs
|
||||||
#undef err
|
#undef err
|
||||||
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
|
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
|
||||||
int found_step_resume = 0;
|
struct bpstat_what retval;
|
||||||
|
|
||||||
for (; bs != NULL; bs = bs->next)
|
for (; bs != NULL; bs = bs->next)
|
||||||
{
|
{
|
||||||
@ -1297,7 +1303,7 @@ bpstat_what (bs)
|
|||||||
if (bs->stop)
|
if (bs->stop)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
found_step_resume = 1;
|
retval.step_resume = 1;
|
||||||
/* We don't handle this via the main_action. */
|
/* We don't handle this via the main_action. */
|
||||||
bs_class = no_effect;
|
bs_class = no_effect;
|
||||||
#if 0
|
#if 0
|
||||||
@ -1307,15 +1313,16 @@ bpstat_what (bs)
|
|||||||
bs_class = bp_nostop;
|
bs_class = bp_nostop;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case bp_call_dummy:
|
||||||
|
/* Make sure the action is stop (silent or noisy), so infrun.c
|
||||||
|
pops the dummy frame. */
|
||||||
|
bs_class = bp_silent;
|
||||||
|
retval.call_dummy = 1;
|
||||||
}
|
}
|
||||||
current_action = table[(int)bs_class][(int)current_action];
|
current_action = table[(int)bs_class][(int)current_action];
|
||||||
}
|
}
|
||||||
{
|
retval.main_action = current_action;
|
||||||
struct bpstat_what retval;
|
return retval;
|
||||||
retval.main_action = current_action;
|
|
||||||
retval.step_resume = found_step_resume;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nonzero if we should step constantly (e.g. watchpoints on machines
|
/* Nonzero if we should step constantly (e.g. watchpoints on machines
|
||||||
@ -1347,7 +1354,7 @@ breakpoint_1 (bnum, allflag)
|
|||||||
CORE_ADDR last_addr = (CORE_ADDR)-1;
|
CORE_ADDR last_addr = (CORE_ADDR)-1;
|
||||||
int found_a_breakpoint = 0;
|
int found_a_breakpoint = 0;
|
||||||
static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
|
static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
|
||||||
"longjmp", "longjmp resume"};
|
"longjmp", "longjmp resume", "step resume"};
|
||||||
static char *bpdisps[] = {"del", "dis", "keep"};
|
static char *bpdisps[] = {"del", "dis", "keep"};
|
||||||
static char bpenables[] = "ny";
|
static char bpenables[] = "ny";
|
||||||
char wrap_indent[80];
|
char wrap_indent[80];
|
||||||
@ -1379,11 +1386,13 @@ breakpoint_1 (bnum, allflag)
|
|||||||
case bp_watchpoint:
|
case bp_watchpoint:
|
||||||
print_expression (b->exp, stdout);
|
print_expression (b->exp, stdout);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bp_breakpoint:
|
case bp_breakpoint:
|
||||||
case bp_until:
|
case bp_until:
|
||||||
case bp_finish:
|
case bp_finish:
|
||||||
case bp_longjmp:
|
case bp_longjmp:
|
||||||
case bp_longjmp_resume:
|
case bp_longjmp_resume:
|
||||||
|
case bp_step_resume:
|
||||||
if (addressprint)
|
if (addressprint)
|
||||||
printf_filtered ("%s ", local_hex_string_custom(b->address, "08"));
|
printf_filtered ("%s ", local_hex_string_custom(b->address, "08"));
|
||||||
|
|
||||||
@ -1403,8 +1412,6 @@ breakpoint_1 (bnum, allflag)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
print_address_symbolic (b->address, stdout, demangle, " ");
|
print_address_symbolic (b->address, stdout, demangle, " ");
|
||||||
/* intentional fall-through */
|
|
||||||
case bp_step_resume: /* do nothing. */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
302
gdb/breakpoint.h
302
gdb/breakpoint.h
@ -29,141 +29,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
#define BREAKPOINT_MAX 16
|
#define BREAKPOINT_MAX 16
|
||||||
|
|
||||||
/* The follow 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;
|
|
||||||
|
|
||||||
/* Interface: */
|
|
||||||
/* Clear a bpstat so that it says we are not at any breakpoint.
|
|
||||||
Also free any storage that is part of a bpstat. */
|
|
||||||
extern void bpstat_clear PARAMS ((bpstat *));
|
|
||||||
|
|
||||||
/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
|
|
||||||
is part of the bpstat is copied as well. */
|
|
||||||
extern bpstat bpstat_copy PARAMS ((bpstat));
|
|
||||||
|
|
||||||
/* Get a bpstat associated with having just stopped at address *PC
|
|
||||||
and frame address FRAME_ADDRESS. Update *PC to point at the
|
|
||||||
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));
|
|
||||||
|
|
||||||
/* Return values from bpstat_what. */
|
|
||||||
enum bpstat_what {
|
|
||||||
/* Perform various other tests; that is, this bpstat does not
|
|
||||||
say to perform any action (e.g. failed watchpoint and nothing
|
|
||||||
else). */
|
|
||||||
BPSTAT_WHAT_KEEP_CHECKING,
|
|
||||||
|
|
||||||
/* Rather than distinguish between noisy and silent stops here, it
|
|
||||||
might be cleaner to have bpstat_print make that decision (also
|
|
||||||
taking into account stop_print_frame and source_only). But the
|
|
||||||
implications are a bit scary (interaction with auto-displays, etc.),
|
|
||||||
so I won't try it. */
|
|
||||||
|
|
||||||
/* Stop silently. */
|
|
||||||
BPSTAT_WHAT_STOP_SILENT,
|
|
||||||
|
|
||||||
/* Stop and print. */
|
|
||||||
BPSTAT_WHAT_STOP_NOISY,
|
|
||||||
|
|
||||||
/* Remove breakpoints, single step once, then put them back in and
|
|
||||||
go back to what we were doing. */
|
|
||||||
BPSTAT_WHAT_SINGLE,
|
|
||||||
|
|
||||||
/* Set longjmp_resume breakpoint, remove all other breakpoints,
|
|
||||||
and continue. The "remove all other breakpoints" part is required
|
|
||||||
if we are also stepping over another breakpoint as well as doing
|
|
||||||
the longjmp handling. */
|
|
||||||
BPSTAT_WHAT_SET_LONGJMP_RESUME,
|
|
||||||
|
|
||||||
/* Clear longjmp_resume breakpoint, then handle as
|
|
||||||
BPSTAT_WHAT_KEEP_CHECKING. */
|
|
||||||
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME,
|
|
||||||
|
|
||||||
/* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */
|
|
||||||
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
|
|
||||||
|
|
||||||
/* This is just used to keep track of how many enums there are. */
|
|
||||||
BPSTAT_WHAT_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Tell what to do about this bpstat. */
|
|
||||||
enum bpstat_what bpstat_what PARAMS ((bpstat));
|
|
||||||
|
|
||||||
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
|
|
||||||
bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *));
|
|
||||||
|
|
||||||
/* Nonzero if a signal that we got in wait() was due to circumstances
|
|
||||||
explained by the BS. */
|
|
||||||
/* Currently that is true if we have hit a breakpoint, or if there is
|
|
||||||
a watchpoint enabled. */
|
|
||||||
#define bpstat_explains_signal(bs) ((bs) != NULL)
|
|
||||||
|
|
||||||
/* Nonzero if we should step constantly (e.g. watchpoints on machines
|
|
||||||
without hardware support). This isn't related to a specific bpstat,
|
|
||||||
just to things like whether watchpoints are set. */
|
|
||||||
extern int bpstat_should_step PARAMS ((void));
|
|
||||||
|
|
||||||
/* Print a message indicating what happened. Returns nonzero to
|
|
||||||
say that only the source line should be printed after this (zero
|
|
||||||
return means print the frame as well as the source line). */
|
|
||||||
extern int bpstat_print PARAMS ((bpstat));
|
|
||||||
|
|
||||||
/* Return 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. */
|
|
||||||
extern int bpstat_num PARAMS ((bpstat *));
|
|
||||||
|
|
||||||
/* Perform actions associated with having stopped at *BSP. */
|
|
||||||
extern void bpstat_do_actions PARAMS ((bpstat *));
|
|
||||||
|
|
||||||
/* Modify BS so that the actions will not be performed. */
|
|
||||||
extern void bpstat_clear_actions PARAMS ((bpstat));
|
|
||||||
|
|
||||||
/* Implementation: */
|
|
||||||
struct bpstat
|
|
||||||
{
|
|
||||||
/* Linked list because there can be two breakpoints at the
|
|
||||||
same place, and a bpstat reflects the fact that both have been hit. */
|
|
||||||
bpstat next;
|
|
||||||
/* Breakpoint that we are at. */
|
|
||||||
struct breakpoint *breakpoint_at;
|
|
||||||
/* Commands left to be done. */
|
|
||||||
struct command_line *commands;
|
|
||||||
/* Old value associated with a watchpoint. */
|
|
||||||
value old_val;
|
|
||||||
|
|
||||||
/* Nonzero if this breakpoint tells us to print the frame. */
|
|
||||||
char print;
|
|
||||||
|
|
||||||
/* Nonzero if this breakpoint tells us to stop. */
|
|
||||||
char stop;
|
|
||||||
|
|
||||||
/* Function called by bpstat_print to print stuff associated with
|
|
||||||
this element of the bpstat chain. Returns 0 or 1 just like
|
|
||||||
bpstat_print, or -1 if it can't deal with it. */
|
|
||||||
int (*print_it) PARAMS((bpstat bs));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Type of breakpoint. */
|
/* Type of breakpoint. */
|
||||||
/* FIXME In the future, we should fold all other breakpoint-like things into
|
/* FIXME In the future, we should fold all other breakpoint-like things into
|
||||||
here. This includes:
|
here. This includes:
|
||||||
|
|
||||||
1) single-step (for machines where we have to simulate single stepping),
|
* call-dummy (the breakpoint at the end of a subroutine stub that gdb
|
||||||
2) step-resume (for 'next'ing over subroutine calls),
|
uses to call functions in the target) (definately).
|
||||||
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)
|
* single-step (for machines where we have to simulate single stepping)
|
||||||
(it is a low-level thing, perhaps the best thing is that it looks
|
(probably, though perhaps it is better for it to look as much as
|
||||||
as much as possible like a single-step to wait_for_inferior)
|
possible like a single-step to wait_for_inferior). */
|
||||||
-kingdon, 8 Apr 93.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum bptype {
|
enum bptype {
|
||||||
bp_breakpoint, /* Normal breakpoint */
|
bp_breakpoint, /* Normal breakpoint */
|
||||||
@ -171,7 +46,14 @@ enum bptype {
|
|||||||
bp_finish, /* used by finish command */
|
bp_finish, /* used by finish command */
|
||||||
bp_watchpoint, /* Watchpoint */
|
bp_watchpoint, /* Watchpoint */
|
||||||
bp_longjmp, /* secret breakpoint to find longjmp() */
|
bp_longjmp, /* secret breakpoint to find longjmp() */
|
||||||
bp_longjmp_resume /* secret breakpoint to escape 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. */
|
/* States of enablement of breakpoint. */
|
||||||
@ -205,14 +87,20 @@ struct breakpoint
|
|||||||
enum bpdisp disposition;
|
enum bpdisp disposition;
|
||||||
/* Number assigned to distinguish breakpoints. */
|
/* Number assigned to distinguish breakpoints. */
|
||||||
int number;
|
int number;
|
||||||
|
|
||||||
/* Address to break at, or NULL if not a breakpoint. */
|
/* Address to break at, or NULL if not a breakpoint. */
|
||||||
CORE_ADDR address;
|
CORE_ADDR address;
|
||||||
/* Line number of this address. Redundant. Only matters if address
|
|
||||||
is non-NULL. */
|
/* Line number of this address. Only matters if address is
|
||||||
|
non-NULL. */
|
||||||
|
|
||||||
int line_number;
|
int line_number;
|
||||||
/* Symtab of file of this address. Redundant. Only matters if address
|
|
||||||
is non-NULL. */
|
/* Source file name of this address. Only matters if address is
|
||||||
struct symtab *symtab;
|
non-NULL. */
|
||||||
|
|
||||||
|
char *source_file;
|
||||||
|
|
||||||
/* Non-zero means a silent breakpoint (don't print frame info
|
/* Non-zero means a silent breakpoint (don't print frame info
|
||||||
if we stop here). */
|
if we stop here). */
|
||||||
unsigned char silent;
|
unsigned char silent;
|
||||||
@ -256,6 +144,148 @@ struct breakpoint
|
|||||||
value val;
|
value val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* Interface: */
|
||||||
|
/* Clear a bpstat so that it says we are not at any breakpoint.
|
||||||
|
Also free any storage that is part of a bpstat. */
|
||||||
|
extern void bpstat_clear PARAMS ((bpstat *));
|
||||||
|
|
||||||
|
/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
|
||||||
|
is part of the bpstat is copied as well. */
|
||||||
|
extern bpstat bpstat_copy PARAMS ((bpstat));
|
||||||
|
|
||||||
|
/* Get a bpstat associated with having just stopped at address *PC
|
||||||
|
and frame address FRAME_ADDRESS. Update *PC to point at the
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* This bpstat_what stuff tells wait_for_inferior what to do with a
|
||||||
|
breakpoint (a challenging task). */
|
||||||
|
|
||||||
|
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_KEEP_CHECKING,
|
||||||
|
|
||||||
|
/* Rather than distinguish between noisy and silent stops here, it
|
||||||
|
might be cleaner to have bpstat_print make that decision (also
|
||||||
|
taking into account stop_print_frame and source_only). But the
|
||||||
|
implications are a bit scary (interaction with auto-displays, etc.),
|
||||||
|
so I won't try it. */
|
||||||
|
|
||||||
|
/* Stop silently. */
|
||||||
|
BPSTAT_WHAT_STOP_SILENT,
|
||||||
|
|
||||||
|
/* Stop and print. */
|
||||||
|
BPSTAT_WHAT_STOP_NOISY,
|
||||||
|
|
||||||
|
/* Remove breakpoints, single step once, then put them back in and
|
||||||
|
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,
|
||||||
|
and continue. The "remove all other breakpoints" part is required
|
||||||
|
if we are also stepping over another breakpoint as well as doing
|
||||||
|
the longjmp handling. */
|
||||||
|
BPSTAT_WHAT_SET_LONGJMP_RESUME,
|
||||||
|
|
||||||
|
/* Clear longjmp_resume breakpoint, then handle as
|
||||||
|
BPSTAT_WHAT_KEEP_CHECKING. */
|
||||||
|
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME,
|
||||||
|
|
||||||
|
/* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */
|
||||||
|
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
|
||||||
|
|
||||||
|
/* This is just used to keep track of how many enums there are. */
|
||||||
|
BPSTAT_WHAT_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* Find the bpstat associated with a breakpoint. NULL otherwise. */
|
||||||
|
bpstat bpstat_find_breakpoint PARAMS ((bpstat, struct breakpoint *));
|
||||||
|
|
||||||
|
/* Nonzero if a signal that we got in wait() was due to circumstances
|
||||||
|
explained by the BS. */
|
||||||
|
/* Currently that is true if we have hit a breakpoint, or if there is
|
||||||
|
a watchpoint enabled. */
|
||||||
|
#define bpstat_explains_signal(bs) ((bs) != NULL)
|
||||||
|
|
||||||
|
/* Nonzero if we should step constantly (e.g. watchpoints on machines
|
||||||
|
without hardware support). This isn't related to a specific bpstat,
|
||||||
|
just to things like whether watchpoints are set. */
|
||||||
|
extern int bpstat_should_step PARAMS ((void));
|
||||||
|
|
||||||
|
/* Print a message indicating what happened. Returns nonzero to
|
||||||
|
say that only the source line should be printed after this (zero
|
||||||
|
return means print the frame as well as the source line). */
|
||||||
|
extern int bpstat_print PARAMS ((bpstat));
|
||||||
|
|
||||||
|
/* Return 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. */
|
||||||
|
extern int bpstat_num PARAMS ((bpstat *));
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
extern void bpstat_clear_actions PARAMS ((bpstat));
|
||||||
|
|
||||||
|
/* Implementation: */
|
||||||
|
struct bpstat
|
||||||
|
{
|
||||||
|
/* Linked list because there can be two breakpoints at the
|
||||||
|
same place, and a bpstat reflects the fact that both have been hit. */
|
||||||
|
bpstat next;
|
||||||
|
/* Breakpoint that we are at. */
|
||||||
|
struct breakpoint *breakpoint_at;
|
||||||
|
/* Commands left to be done. */
|
||||||
|
struct command_line *commands;
|
||||||
|
/* Old value associated with a watchpoint. */
|
||||||
|
value old_val;
|
||||||
|
|
||||||
|
/* Nonzero if this breakpoint tells us to print the frame. */
|
||||||
|
char print;
|
||||||
|
|
||||||
|
/* Nonzero if this breakpoint tells us to stop. */
|
||||||
|
char stop;
|
||||||
|
|
||||||
|
/* Function called by bpstat_print to print stuff associated with
|
||||||
|
this element of the bpstat chain. Returns 0 or 1 just like
|
||||||
|
bpstat_print, or -1 if it can't deal with it. */
|
||||||
|
int (*print_it) PARAMS((bpstat bs));
|
||||||
|
};
|
||||||
|
|
||||||
/* Prototypes for breakpoint-related functions. */
|
/* Prototypes for breakpoint-related functions. */
|
||||||
|
|
||||||
#ifdef __STDC__ /* Forward declarations for prototypes */
|
#ifdef __STDC__ /* Forward declarations for prototypes */
|
||||||
|
@ -554,6 +554,8 @@ arguments. */
|
|||||||
|
|
||||||
#define CALL_DUMMY_START_OFFSET 148
|
#define CALL_DUMMY_START_OFFSET 148
|
||||||
|
|
||||||
|
#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
|
||||||
|
|
||||||
#define CALL_DUMMY_STACK_ADJUST 68
|
#define CALL_DUMMY_STACK_ADJUST 68
|
||||||
|
|
||||||
/* Insert the specified number of args and function address
|
/* Insert the specified number of args and function address
|
||||||
|
@ -180,7 +180,7 @@ discard_cleanups PARAMS ((struct cleanup *));
|
|||||||
|
|
||||||
Should be, once all calls and called-functions are cleaned up:
|
Should be, once all calls and called-functions are cleaned up:
|
||||||
extern struct cleanup *
|
extern struct cleanup *
|
||||||
make_cleanup PARAMS ((void (*function) (PTR), PTR));
|
make_cleanup PARAMS ((void (*function) (void *), void *));
|
||||||
|
|
||||||
Until then, lint and/or various type-checking compiler options will
|
Until then, lint and/or various type-checking compiler options will
|
||||||
complain about make_cleanup calls. It'd be wrong to just cast things,
|
complain about make_cleanup calls. It'd be wrong to just cast things,
|
||||||
|
40
gdb/infcmd.c
40
gdb/infcmd.c
@ -497,6 +497,15 @@ signal_command (signum_exp, from_tty)
|
|||||||
proceed (stop_pc, signum, 0);
|
proceed (stop_pc, signum, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call breakpoint_auto_delete on the current contents of the bpstat
|
||||||
|
pointed to by arg (which is really a bpstat *). */
|
||||||
|
void
|
||||||
|
breakpoint_auto_delete_contents (arg)
|
||||||
|
PTR arg;
|
||||||
|
{
|
||||||
|
breakpoint_auto_delete (*(bpstat *)arg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Execute a "stack dummy", a piece of code stored in the stack
|
/* Execute a "stack dummy", a piece of code stored in the stack
|
||||||
by the debugger to be executed in the inferior.
|
by the debugger to be executed in the inferior.
|
||||||
|
|
||||||
@ -522,6 +531,8 @@ run_stack_dummy (addr, buffer)
|
|||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
char buffer[REGISTER_BYTES];
|
char buffer[REGISTER_BYTES];
|
||||||
{
|
{
|
||||||
|
struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
|
||||||
|
|
||||||
/* Now proceed, having reached the desired place. */
|
/* Now proceed, having reached the desired place. */
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
if (stack_dummy_testing & 4)
|
if (stack_dummy_testing & 4)
|
||||||
@ -529,9 +540,38 @@ run_stack_dummy (addr, buffer)
|
|||||||
POP_FRAME;
|
POP_FRAME;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
#ifdef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||||
|
{
|
||||||
|
struct breakpoint *bpt;
|
||||||
|
struct symtab_and_line sal;
|
||||||
|
|
||||||
|
sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
|
||||||
|
sal.symtab = NULL;
|
||||||
|
sal.line = 0;
|
||||||
|
|
||||||
|
/* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to put
|
||||||
|
a breakpoint instruction. If not, the call dummy already has the
|
||||||
|
breakpoint instruction in it.
|
||||||
|
|
||||||
|
addr is the address of the call dummy plus the CALL_DUMMY_START_OFFSET,
|
||||||
|
so we need to subtract the CALL_DUMMY_START_OFFSET. */
|
||||||
|
bpt = set_momentary_breakpoint (sal,
|
||||||
|
NULL,
|
||||||
|
bp_call_dummy);
|
||||||
|
bpt->disposition = delete;
|
||||||
|
|
||||||
|
/* If all error()s out of proceed ended up calling normal_stop (and
|
||||||
|
perhaps they should; it already does in the special case of error
|
||||||
|
out of resume()), then we wouldn't need this. */
|
||||||
|
make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
|
||||||
|
}
|
||||||
|
#endif /* CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||||
|
|
||||||
proceed_to_finish = 1; /* We want stop_registers, please... */
|
proceed_to_finish = 1; /* We want stop_registers, please... */
|
||||||
proceed (addr, 0, 0);
|
proceed (addr, 0, 0);
|
||||||
|
|
||||||
|
discard_cleanups (old_cleanups);
|
||||||
|
|
||||||
if (!stop_stack_dummy)
|
if (!stop_stack_dummy)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
22
gdb/infrun.c
22
gdb/infrun.c
@ -721,7 +721,9 @@ wait_for_inferior ()
|
|||||||
random_signal
|
random_signal
|
||||||
= !(bpstat_explains_signal (stop_bpstat)
|
= !(bpstat_explains_signal (stop_bpstat)
|
||||||
|| trap_expected
|
|| trap_expected
|
||||||
|
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||||
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
||||||
|
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||||
|| (step_range_end && step_resume_breakpoint == NULL));
|
|| (step_range_end && step_resume_breakpoint == NULL));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -730,7 +732,9 @@ wait_for_inferior ()
|
|||||||
/* End of a stack dummy. Some systems (e.g. Sony
|
/* End of a stack dummy. Some systems (e.g. Sony
|
||||||
news) give another signal besides SIGTRAP,
|
news) give another signal besides SIGTRAP,
|
||||||
so check here as well as above. */
|
so check here as well as above. */
|
||||||
|
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||||
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
||||||
|
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||||
);
|
);
|
||||||
if (!random_signal)
|
if (!random_signal)
|
||||||
stop_signal = SIGTRAP;
|
stop_signal = SIGTRAP;
|
||||||
@ -793,6 +797,14 @@ wait_for_inferior ()
|
|||||||
|
|
||||||
what = bpstat_what (stop_bpstat);
|
what = bpstat_what (stop_bpstat);
|
||||||
|
|
||||||
|
if (what.call_dummy)
|
||||||
|
{
|
||||||
|
stop_stack_dummy = 1;
|
||||||
|
#ifdef HP_OS_BUG
|
||||||
|
trap_expected_after_continue = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
switch (what.main_action)
|
switch (what.main_action)
|
||||||
{
|
{
|
||||||
case BPSTAT_WHAT_SET_LONGJMP_RESUME:
|
case BPSTAT_WHAT_SET_LONGJMP_RESUME:
|
||||||
@ -887,6 +899,12 @@ wait_for_inferior ()
|
|||||||
test for stepping. But, if not stepping,
|
test for stepping. But, if not stepping,
|
||||||
do not stop. */
|
do not stop. */
|
||||||
|
|
||||||
|
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||||
|
/* This is the old way of detecting the end of the stack dummy.
|
||||||
|
An architecture which defines CALL_DUMMY_BREAKPOINT_OFFSET gets
|
||||||
|
handled above. As soon as we can test it on all of them, all
|
||||||
|
architectures should define it. */
|
||||||
|
|
||||||
/* If this is the breakpoint at the end of a stack dummy,
|
/* If this is the breakpoint at the end of a stack dummy,
|
||||||
just stop silently, unless the user was doing an si/ni, in which
|
just stop silently, unless the user was doing an si/ni, in which
|
||||||
case she'd better know what she's doing. */
|
case she'd better know what she's doing. */
|
||||||
@ -901,6 +919,7 @@ wait_for_inferior ()
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||||
|
|
||||||
if (step_resume_breakpoint)
|
if (step_resume_breakpoint)
|
||||||
/* Having a step-resume breakpoint overrides anything
|
/* Having a step-resume breakpoint overrides anything
|
||||||
@ -1081,8 +1100,7 @@ step_into_function:
|
|||||||
since on some machines the prologue
|
since on some machines the prologue
|
||||||
is where the new fp value is established. */
|
is where the new fp value is established. */
|
||||||
step_resume_breakpoint =
|
step_resume_breakpoint =
|
||||||
set_momentary_breakpoint (sr_sal, (CORE_ADDR)0,
|
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
|
||||||
bp_step_resume);
|
|
||||||
if (breakpoints_inserted)
|
if (breakpoints_inserted)
|
||||||
insert_breakpoints ();
|
insert_breakpoints ();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user