import gdb-2000-01-05 snapshot

This commit is contained in:
Jason Molenda 2000-01-06 03:07:20 +00:00
parent 1b45fe546b
commit c3f6f71df3
74 changed files with 18148 additions and 14752 deletions

View file

@ -4164,107 +4164,135 @@ mention (b)
}
/* Set a breakpoint according to ARG (function, linenum or *address)
flag: first bit : 0 non-temporary, 1 temporary.
second bit : 0 normal breakpoint, 1 hardware breakpoint. */
/* Add SALS.nelts breakpoints to the breakpoint table. For each
SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
COND[i] and COND_STRING[i] values.
NOTE: If the function succeeds, the caller is expected to cleanup
the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
array contents). If the function fails (error() is called), the
caller is expected to cleanups both the ADDR_STRING, COND_STRING,
COND and SALS arrays and each of those arrays contents. */
static void
break_command_1 (arg, flag, from_tty)
char *arg;
int flag, from_tty;
create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
struct expression **cond, char **cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int ignore_count, int from_tty)
{
int tempflag, hardwareflag;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
register struct expression *cond = 0;
register struct breakpoint *b;
if (type == bp_hardware_breakpoint)
{
int i = hw_breakpoint_used_count ();
int target_resources_ok =
TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
i + sals.nelts, 0);
if (target_resources_ok == 0)
error ("No hardware breakpoint support in the target.");
else if (target_resources_ok < 0)
error ("Hardware breakpoints used exceeds limit.");
}
/* Pointers in arg to the start, and one past the end, of the condition. */
char *cond_start = NULL;
char *cond_end = NULL;
/* Pointers in arg to the start, and one past the end,
of the address part. */
char *addr_start = NULL;
char *addr_end = NULL;
struct cleanup *old_chain;
struct cleanup *canonical_strings_chain = NULL;
char **canonical = (char **) NULL;
int i;
int thread;
/* Now set all the breakpoints. */
{
int i;
for (i = 0; i < sals.nelts; i++)
{
struct breakpoint *b;
struct symtab_and_line sal = sals.sals[i];
hardwareflag = flag & BP_HARDWAREFLAG;
tempflag = flag & BP_TEMPFLAG;
if (from_tty)
describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->type = type;
b->cond = cond[i];
b->thread = thread;
b->addr_string = addr_string[i];
b->cond_string = cond_string[i];
b->ignore_count = ignore_count;
b->enable = enabled;
b->disposition = disposition;
mention (b);
}
}
}
sals.sals = NULL;
sals.nelts = 0;
/* Parse ARG which is assumed to be a SAL specification possibly
followed by conditionals. On return, SALS contains an array of SAL
addresses found. ADDR_STRING contains a vector of (canonical)
address strings. ARG points to the end of the SAL. */
INIT_SAL (&sal); /* initialize to zeroes */
/* If no arg given, or if first arg is 'if ', use the default breakpoint. */
if (!arg || (arg[0] == 'i' && arg[1] == 'f'
&& (arg[2] == ' ' || arg[2] == '\t')))
void
parse_breakpoint_sals (char **address,
struct symtabs_and_lines *sals,
char ***addr_string)
{
char *addr_start = *address;
*addr_string = NULL;
/* If no arg given, or if first arg is 'if ', use the default
breakpoint. */
if ((*address) == NULL
|| (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
{
if (default_breakpoint_valid)
{
sals.sals = (struct symtab_and_line *)
struct symtab_and_line sal;
INIT_SAL (&sal); /* initialize to zeroes */
sals->sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
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;
sals->sals[0] = sal;
sals->nelts = 1;
}
else
error ("No default breakpoint address now.");
}
else
{
addr_start = arg;
/* Force almost all breakpoints to be in terms of the
current_source_symtab (which is decode_line_1's default). This
should produce the results we want almost all of the time while
leaving default_breakpoint_* alone. */
if (default_breakpoint_valid
&& (!current_source_symtab
|| (arg && (*arg == '+' || *arg == '-'))))
sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
default_breakpoint_line, &canonical);
|| (strchr ("+-", (*address)[0]) != NULL)))
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
default_breakpoint_line, addr_string);
else
sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical);
addr_end = arg;
*sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
}
if (!sals.nelts)
return;
/* Make sure that all storage allocated in decode_line_1 gets freed
in case the following `for' loop errors out. */
old_chain = make_cleanup (free, sals.sals);
if (canonical != (char **) NULL)
/* For any SAL that didn't have a canonical string, fill one in. */
if (sals->nelts > 0 && *addr_string == NULL)
*addr_string = xcalloc (sals->nelts, sizeof (char **));
if (addr_start != (*address))
{
make_cleanup (free, canonical);
canonical_strings_chain = make_cleanup (null_cleanup, 0);
for (i = 0; i < sals.nelts; i++)
int i;
for (i = 0; i < sals->nelts; i++)
{
if (canonical[i] != NULL)
make_cleanup (free, canonical[i]);
/* Add the string if not present. */
if ((*addr_string)[i] == NULL)
(*addr_string)[i] = savestring (addr_start, (*address) - addr_start);
}
}
}
thread = -1; /* No specific thread yet */
/* Resolve all line numbers to PC's, and verify that conditions
can be parsed, before setting any breakpoints. */
for (i = 0; i < sals.nelts; i++)
/* Convert each SAL into a real PC. Verify that the PC can be
inserted as a breakpoint. If it can't throw an error. */
void
breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
char *address)
{
int i;
for (i = 0; i < sals->nelts; i++)
{
char *tok, *end_tok;
int toklen;
resolve_sal_pc (&sals.sals[i]);
resolve_sal_pc (&sals->sals[i]);
/* It's possible for the PC to be nonzero, but still an illegal
value on some targets.
@ -4279,16 +4307,100 @@ break_command_1 (arg, flag, from_tty)
Give the target a chance to bless sals.sals[i].pc before we
try to make a breakpoint for it. */
if (PC_REQUIRES_RUN_BEFORE_USE (sals.sals[i].pc))
if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
{
error ("Cannot break on %s without a running program.",
addr_start);
if (address == NULL)
error ("Cannot break without a running program.");
else
error ("Cannot break on %s without a running program.",
address);
}
}
}
tok = arg;
/* Set a breakpoint according to ARG (function, linenum or *address)
flag: first bit : 0 non-temporary, 1 temporary.
second bit : 0 normal breakpoint, 1 hardware breakpoint. */
static void
break_command_1 (arg, flag, from_tty)
char *arg;
int flag, from_tty;
{
int tempflag, hardwareflag;
struct symtabs_and_lines sals;
register struct expression **cond = 0;
/* Pointers in arg to the start, and one past the end, of the
condition. */
char **cond_string = (char **) NULL;
char *addr_start = arg;
char **addr_string;
struct cleanup *old_chain;
struct cleanup *breakpoint_chain = NULL;
int i;
int thread = -1;
int ignore_count = 0;
hardwareflag = flag & BP_HARDWAREFLAG;
tempflag = flag & BP_TEMPFLAG;
sals.sals = NULL;
sals.nelts = 0;
addr_string = NULL;
parse_breakpoint_sals (&arg, &sals, &addr_string);
if (!sals.nelts)
return;
/* Create a chain of things that always need to be cleaned up. */
old_chain = make_cleanup (null_cleanup, 0);
/* Make sure that all storage allocated to SALS gets freed. */
make_cleanup (free, sals.sals);
/* Cleanup the addr_string array but not its contents. */
make_cleanup (free, addr_string);
/* Allocate space for all the cond expressions. */
cond = xcalloc (sals.nelts, sizeof (struct expression *));
make_cleanup (free, cond);
/* Allocate space for all the cond strings. */
cond_string = xcalloc (sals.nelts, sizeof (char **));
make_cleanup (free, cond_string);
/* ----------------------------- SNIP -----------------------------
Anything added to the cleanup chain beyond this point is assumed
to be part of a breakpoint. If the breakpoint create succeeds
then the memory is not reclaimed. */
breakpoint_chain = make_cleanup (null_cleanup, 0);
/* Mark the contents of the addr_string for cleanup. These go on
the breakpoint_chain and only occure if the breakpoint create
fails. */
for (i = 0; i < sals.nelts; i++)
{
if (addr_string[i] != NULL)
make_cleanup (free, addr_string[i]);
}
/* Resolve all line numbers to PC's and verify that the addresses
are ok for the target. */
breakpoint_sals_to_pc (&sals, addr_start);
/* Verify that condition can be parsed, before setting any
breakpoints. Allocate a separate condition expression for each
breakpoint. */
thread = -1; /* No specific thread yet */
for (i = 0; i < sals.nelts; i++)
{
char *tok = arg;
while (tok && *tok)
{
char *end_tok;
int toklen;
char *cond_start = NULL;
char *cond_end = NULL;
while (*tok == ' ' || *tok == '\t')
tok++;
@ -4302,8 +4414,11 @@ break_command_1 (arg, flag, from_tty)
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
tok = cond_start = end_tok + 1;
cond = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
make_cleanup (free, cond[i]);
cond_end = tok;
cond_string[i] = savestring (cond_start, cond_end - cond_start);
make_cleanup (free, cond_string[i]);
}
else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
{
@ -4321,61 +4436,149 @@ break_command_1 (arg, flag, from_tty)
error ("Junk at end of arguments.");
}
}
if (hardwareflag)
{
int i, target_resources_ok;
i = hw_breakpoint_used_count ();
target_resources_ok =
TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
i + sals.nelts, 0);
if (target_resources_ok == 0)
error ("No hardware breakpoint support in the target.");
else if (target_resources_ok < 0)
error ("Hardware breakpoints used exceeds limit.");
}
/* Remove the canonical strings from the cleanup, they are needed below. */
if (canonical != (char **) NULL)
discard_cleanups (canonical_strings_chain);
/* Now set all the breakpoints. */
for (i = 0; i < sals.nelts; i++)
{
sal = sals.sals[i];
if (from_tty)
describe_other_breakpoints (sal.pc, sal.section);
b = set_raw_breakpoint (sal);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->type = hardwareflag ? bp_hardware_breakpoint : bp_breakpoint;
b->cond = cond;
b->thread = thread;
/* If a canonical line spec is needed use that instead of the
command string. */
if (canonical != (char **) NULL && canonical[i] != NULL)
b->addr_string = canonical[i];
else if (addr_start)
b->addr_string = savestring (addr_start, addr_end - addr_start);
if (cond_start)
b->cond_string = savestring (cond_start, cond_end - cond_start);
b->enable = enabled;
b->disposition = tempflag ? del : donttouch;
mention (b);
}
create_breakpoints (sals, addr_string, cond, cond_string,
hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
tempflag ? del : donttouch,
thread, ignore_count, from_tty);
if (sals.nelts > 1)
{
warning ("Multiple breakpoints were set.");
warning ("Use the \"delete\" command to delete unwanted breakpoints.");
}
/* That's it. Discard the cleanups for data inserted into the
breakpoint. */
discard_cleanups (breakpoint_chain);
/* But cleanup everything else. */
do_cleanups (old_chain);
}
/* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
linenum or *address) with COND and IGNORE_COUNT. */
struct captured_breakpoint_args
{
char *address;
char *condition;
int hardwareflag;
int tempflag;
int thread;
int ignore_count;
};
static int
do_captured_breakpoint (void *data)
{
struct captured_breakpoint_args *args = data;
struct symtabs_and_lines sals;
register struct expression **cond;
struct cleanup *old_chain;
struct cleanup *breakpoint_chain = NULL;
int i;
char **addr_string;
char **cond_string;
char *address_end;
/* Parse the source and lines spec. Delay check that the expression
didn't contain trailing garbage until after cleanups are in
place. */
sals.sals = NULL;
sals.nelts = 0;
address_end = args->address;
addr_string = NULL;
parse_breakpoint_sals (&address_end, &sals, &addr_string);
if (!sals.nelts)
return GDB_RC_NONE;
/* Create a chain of things at always need to be cleaned up. */
old_chain = make_cleanup (null_cleanup, 0);
/* Always have a addr_string array, even if it is empty. */
make_cleanup (free, addr_string);
/* Make sure that all storage allocated to SALS gets freed. */
make_cleanup (free, sals.sals);
/* Allocate space for all the cond expressions. */
cond = xcalloc (sals.nelts, sizeof (struct expression *));
make_cleanup (free, cond);
/* Allocate space for all the cond strings. */
cond_string = xcalloc (sals.nelts, sizeof (char **));
make_cleanup (free, cond_string);
/* ----------------------------- SNIP -----------------------------
Anything added to the cleanup chain beyond this point is assumed
to be part of a breakpoint. If the breakpoint create goes
through then that memory is not cleaned up. */
breakpoint_chain = make_cleanup (null_cleanup, 0);
/* Mark the contents of the addr_string for cleanup. These go on
the breakpoint_chain and only occure if the breakpoint create
fails. */
for (i = 0; i < sals.nelts; i++)
{
if (addr_string[i] != NULL)
make_cleanup (free, addr_string[i]);
}
/* Wait until now before checking for garbage at the end of the
address. That way cleanups can take care of freeing any
memory. */
if (*address_end != '\0')
error ("Garbage %s following breakpoint address", address_end);
/* Resolve all line numbers to PC's. */
breakpoint_sals_to_pc (&sals, args->address);
/* Verify that conditions can be parsed, before setting any
breakpoints. */
for (i = 0; i < sals.nelts; i++)
{
if (args->condition != NULL)
{
char *tok = args->condition;
cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
if (*tok != '\0')
error ("Garbage %s follows condition", tok);
make_cleanup (free, cond[i]);
cond_string[i] = xstrdup (args->condition);
}
}
create_breakpoints (sals, addr_string, cond, cond_string,
args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
args->tempflag ? del : donttouch,
args->thread, args->ignore_count, 0/*from-tty*/);
/* That's it. Discard the cleanups for data inserted into the
breakpoint. */
discard_cleanups (breakpoint_chain);
/* But cleanup everything else. */
do_cleanups (old_chain);
return GDB_RC_OK;
}
enum gdb_rc
gdb_breakpoint (char *address, char *condition,
int hardwareflag, int tempflag,
int thread, int ignore_count)
{
struct captured_breakpoint_args args;
args.address = address;
args.condition = condition;
args.hardwareflag = hardwareflag;
args.tempflag = tempflag;
args.thread = thread;
args.ignore_count = ignore_count;
return catch_errors (do_captured_breakpoint, &args,
NULL, RETURN_MASK_ALL);
}
static void
break_at_finish_at_depth_command_1 (arg, flag, from_tty)
char *arg;