* 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:
parent
fa79d853b8
commit
84d598611e
@ -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.c: Add remote debug feature. Rename stuff to distinguish
|
||||
|
@ -1221,6 +1221,12 @@ bpstat_what (bs)
|
||||
#define err BPSTAT_WHAT_STOP_NOISY
|
||||
|
||||
/* 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
|
||||
table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
|
||||
{
|
||||
@ -1245,7 +1251,7 @@ bpstat_what (bs)
|
||||
#undef clrlrs
|
||||
#undef err
|
||||
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)
|
||||
{
|
||||
@ -1297,7 +1303,7 @@ bpstat_what (bs)
|
||||
if (bs->stop)
|
||||
{
|
||||
#endif
|
||||
found_step_resume = 1;
|
||||
retval.step_resume = 1;
|
||||
/* We don't handle this via the main_action. */
|
||||
bs_class = no_effect;
|
||||
#if 0
|
||||
@ -1307,15 +1313,16 @@ bpstat_what (bs)
|
||||
bs_class = bp_nostop;
|
||||
#endif
|
||||
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];
|
||||
}
|
||||
{
|
||||
struct bpstat_what retval;
|
||||
retval.main_action = current_action;
|
||||
retval.step_resume = found_step_resume;
|
||||
return retval;
|
||||
}
|
||||
retval.main_action = current_action;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
int found_a_breakpoint = 0;
|
||||
static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
|
||||
"longjmp", "longjmp resume"};
|
||||
"longjmp", "longjmp resume", "step resume"};
|
||||
static char *bpdisps[] = {"del", "dis", "keep"};
|
||||
static char bpenables[] = "ny";
|
||||
char wrap_indent[80];
|
||||
@ -1379,11 +1386,13 @@ breakpoint_1 (bnum, allflag)
|
||||
case bp_watchpoint:
|
||||
print_expression (b->exp, stdout);
|
||||
break;
|
||||
|
||||
case bp_breakpoint:
|
||||
case bp_until:
|
||||
case bp_finish:
|
||||
case bp_longjmp:
|
||||
case bp_longjmp_resume:
|
||||
case bp_step_resume:
|
||||
if (addressprint)
|
||||
printf_filtered ("%s ", local_hex_string_custom(b->address, "08"));
|
||||
|
||||
@ -1403,8 +1412,6 @@ breakpoint_1 (bnum, allflag)
|
||||
}
|
||||
else
|
||||
print_address_symbolic (b->address, stdout, demangle, " ");
|
||||
/* intentional fall-through */
|
||||
case bp_step_resume: /* do nothing. */
|
||||
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
|
||||
|
||||
/* 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. */
|
||||
/* 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).
|
||||
* call-dummy (the breakpoint at the end of a subroutine stub that gdb
|
||||
uses to call functions in the target) (definately).
|
||||
|
||||
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.
|
||||
*/
|
||||
* 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 */
|
||||
@ -171,7 +46,14 @@ enum bptype {
|
||||
bp_finish, /* used by finish command */
|
||||
bp_watchpoint, /* Watchpoint */
|
||||
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. */
|
||||
@ -205,14 +87,20 @@ struct breakpoint
|
||||
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. */
|
||||
|
||||
/* Line number of this address. 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;
|
||||
|
||||
/* 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;
|
||||
@ -256,6 +144,148 @@ struct breakpoint
|
||||
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. */
|
||||
|
||||
#ifdef __STDC__ /* Forward declarations for prototypes */
|
||||
|
@ -554,6 +554,8 @@ arguments. */
|
||||
|
||||
#define CALL_DUMMY_START_OFFSET 148
|
||||
|
||||
#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
|
||||
|
||||
#define CALL_DUMMY_STACK_ADJUST 68
|
||||
|
||||
/* 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:
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
by the debugger to be executed in the inferior.
|
||||
|
||||
@ -522,6 +531,8 @@ run_stack_dummy (addr, buffer)
|
||||
CORE_ADDR addr;
|
||||
char buffer[REGISTER_BYTES];
|
||||
{
|
||||
struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
|
||||
|
||||
/* Now proceed, having reached the desired place. */
|
||||
clear_proceed_status ();
|
||||
if (stack_dummy_testing & 4)
|
||||
@ -529,9 +540,38 @@ run_stack_dummy (addr, buffer)
|
||||
POP_FRAME;
|
||||
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 (addr, 0, 0);
|
||||
|
||||
discard_cleanups (old_cleanups);
|
||||
|
||||
if (!stop_stack_dummy)
|
||||
return 1;
|
||||
|
||||
|
24
gdb/infrun.c
24
gdb/infrun.c
@ -721,7 +721,9 @@ wait_for_inferior ()
|
||||
random_signal
|
||||
= !(bpstat_explains_signal (stop_bpstat)
|
||||
|| trap_expected
|
||||
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
||||
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||
|| (step_range_end && step_resume_breakpoint == NULL));
|
||||
else
|
||||
{
|
||||
@ -730,7 +732,9 @@ wait_for_inferior ()
|
||||
/* End of a stack dummy. Some systems (e.g. Sony
|
||||
news) give another signal besides SIGTRAP,
|
||||
so check here as well as above. */
|
||||
#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
|
||||
|| PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
|
||||
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||
);
|
||||
if (!random_signal)
|
||||
stop_signal = SIGTRAP;
|
||||
@ -793,6 +797,14 @@ wait_for_inferior ()
|
||||
|
||||
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)
|
||||
{
|
||||
case BPSTAT_WHAT_SET_LONGJMP_RESUME:
|
||||
@ -887,6 +899,12 @@ wait_for_inferior ()
|
||||
test for stepping. But, if not stepping,
|
||||
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,
|
||||
just stop silently, unless the user was doing an si/ni, in which
|
||||
case she'd better know what she's doing. */
|
||||
@ -901,7 +919,8 @@ wait_for_inferior ()
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET. */
|
||||
|
||||
if (step_resume_breakpoint)
|
||||
/* Having a step-resume breakpoint overrides anything
|
||||
else having to do with stepping commands until
|
||||
@ -1081,8 +1100,7 @@ step_into_function:
|
||||
since on some machines the prologue
|
||||
is where the new fp value is established. */
|
||||
step_resume_breakpoint =
|
||||
set_momentary_breakpoint (sr_sal, (CORE_ADDR)0,
|
||||
bp_step_resume);
|
||||
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
|
||||
if (breakpoints_inserted)
|
||||
insert_breakpoints ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user