* breakpoint.c (create_breakpoint): Split from
create_breakpoints, implementing most of its logic. Take just a single sal, single address string and single condition. Do not take parsed condition at all. (create_breakpoints): Just call create_breakpoint for each sal. (find_condition_and_thread): New. (break_command_1): Use find_condition_and_thread. Do not keep parsed conditions. (do_captured_breakpoint): Don't convert condition string to struct expression.
This commit is contained in:
parent
511a6cd4e1
commit
018d34a46b
@ -1,6 +1,20 @@
|
|||||||
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
|
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
|
||||||
|
|
||||||
gdb/
|
* breakpoint.c (create_breakpoint): Split from
|
||||||
|
create_breakpoints, implementing most of its logic.
|
||||||
|
Take just a single sal, single address string and
|
||||||
|
single condition. Do not take parsed condition at
|
||||||
|
all.
|
||||||
|
(create_breakpoints): Just call create_breakpoint
|
||||||
|
for each sal.
|
||||||
|
(find_condition_and_thread): New.
|
||||||
|
(break_command_1): Use find_condition_and_thread.
|
||||||
|
Do not keep parsed conditions.
|
||||||
|
(do_captured_breakpoint): Don't convert
|
||||||
|
condition string to struct expression.
|
||||||
|
|
||||||
|
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
|
||||||
|
|
||||||
* breakpoint.h (struct breakpoint): Move the cond
|
* breakpoint.h (struct breakpoint): Move the cond
|
||||||
field to...
|
field to...
|
||||||
(struct bp_location): Here.
|
(struct bp_location): Here.
|
||||||
|
255
gdb/breakpoint.c
255
gdb/breakpoint.c
@ -4984,63 +4984,44 @@ mention (struct breakpoint *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
|
|
||||||
The parameter PENDING_BP points to a pending breakpoint that is
|
/* Create a breakpoint with SAL as location. Use ADDR_STRING
|
||||||
the basis of the breakpoints currently being created. The pending
|
as textual description of the location, and COND_STRING
|
||||||
breakpoint may contain a separate condition string or commands
|
as condition expression.
|
||||||
that were added after the initial pending breakpoint was created.
|
|
||||||
|
|
||||||
NOTE: If the function succeeds, the caller is expected to cleanup
|
The paramter PENDING_BP is same as for the
|
||||||
the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
|
create_breakpoints function. */
|
||||||
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
|
static void
|
||||||
create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
|
create_breakpoint (struct symtab_and_line sal, char *addr_string,
|
||||||
struct expression **cond, char **cond_string,
|
char *cond_string,
|
||||||
enum bptype type, enum bpdisp disposition,
|
enum bptype type, enum bpdisp disposition,
|
||||||
int thread, int ignore_count, int from_tty,
|
int thread, int ignore_count, int from_tty,
|
||||||
struct breakpoint *pending_bp)
|
struct breakpoint *pending_bp)
|
||||||
{
|
{
|
||||||
|
struct breakpoint *b;
|
||||||
|
|
||||||
if (type == bp_hardware_breakpoint)
|
if (type == bp_hardware_breakpoint)
|
||||||
{
|
{
|
||||||
int i = hw_breakpoint_used_count ();
|
int i = hw_breakpoint_used_count ();
|
||||||
int target_resources_ok =
|
int target_resources_ok =
|
||||||
TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
|
TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint,
|
||||||
i + sals.nelts, 0);
|
i + 1, 0);
|
||||||
if (target_resources_ok == 0)
|
if (target_resources_ok == 0)
|
||||||
error (_("No hardware breakpoint support in the target."));
|
error (_("No hardware breakpoint support in the target."));
|
||||||
else if (target_resources_ok < 0)
|
else if (target_resources_ok < 0)
|
||||||
error (_("Hardware breakpoints used exceeds limit."));
|
error (_("Hardware breakpoints used exceeds limit."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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];
|
|
||||||
|
|
||||||
if (from_tty)
|
if (from_tty)
|
||||||
describe_other_breakpoints (sal.pc, sal.section, thread);
|
describe_other_breakpoints (sal.pc, sal.section, thread);
|
||||||
|
|
||||||
b = set_raw_breakpoint (sal, type);
|
b = set_raw_breakpoint (sal, type);
|
||||||
set_breakpoint_count (breakpoint_count + 1);
|
set_breakpoint_count (breakpoint_count + 1);
|
||||||
b->number = breakpoint_count;
|
b->number = breakpoint_count;
|
||||||
b->loc->cond = cond[i];
|
|
||||||
b->thread = thread;
|
b->thread = thread;
|
||||||
if (addr_string[i])
|
|
||||||
b->addr_string = addr_string[i];
|
b->cond_string = cond_string;
|
||||||
else
|
|
||||||
/* addr_string has to be used or breakpoint_re_set will delete
|
|
||||||
me. */
|
|
||||||
b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
|
|
||||||
b->cond_string = cond_string[i];
|
|
||||||
b->ignore_count = ignore_count;
|
b->ignore_count = ignore_count;
|
||||||
b->enable_state = bp_enabled;
|
b->enable_state = bp_enabled;
|
||||||
b->disposition = disposition;
|
b->disposition = disposition;
|
||||||
@ -5050,15 +5031,10 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
|
|||||||
initially specified with the initial breakpoint command. */
|
initially specified with the initial breakpoint command. */
|
||||||
if (pending_bp)
|
if (pending_bp)
|
||||||
{
|
{
|
||||||
char *arg;
|
|
||||||
if (pending_bp->cond_string)
|
if (pending_bp->cond_string)
|
||||||
{
|
b->cond_string = savestring (pending_bp->cond_string,
|
||||||
arg = pending_bp->cond_string;
|
strlen (pending_bp->cond_string));
|
||||||
b->cond_string = savestring (arg, strlen (arg));
|
|
||||||
b->loc->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
|
|
||||||
if (*arg)
|
|
||||||
error (_("Junk at end of pending breakpoint condition expression"));
|
|
||||||
}
|
|
||||||
/* If there are commands associated with the breakpoint, they should
|
/* If there are commands associated with the breakpoint, they should
|
||||||
be copied too. */
|
be copied too. */
|
||||||
if (pending_bp->commands)
|
if (pending_bp->commands)
|
||||||
@ -5068,9 +5044,65 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
|
|||||||
b->ignore_count = pending_bp->ignore_count;
|
b->ignore_count = pending_bp->ignore_count;
|
||||||
b->thread = pending_bp->thread;
|
b->thread = pending_bp->thread;
|
||||||
}
|
}
|
||||||
mention (b);
|
|
||||||
|
if (b->cond_string)
|
||||||
|
{
|
||||||
|
char *arg = b->cond_string;
|
||||||
|
b->loc->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
|
||||||
|
if (*arg)
|
||||||
|
{
|
||||||
|
if (pending_bp)
|
||||||
|
error (_("Junk at end of pending breakpoint condition expression"));
|
||||||
|
else
|
||||||
|
error (_("Garbage %s follows condition"), arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr_string)
|
||||||
|
b->addr_string = addr_string;
|
||||||
|
else
|
||||||
|
/* addr_string has to be used or breakpoint_re_set will delete
|
||||||
|
me. */
|
||||||
|
b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
|
||||||
|
|
||||||
|
mention (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add SALS.nelts breakpoints to the breakpoint table. For each
|
||||||
|
SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i]
|
||||||
|
value. COND_STRING, if not NULL, specified the condition to be
|
||||||
|
used for all breakpoints. Essentially the only case where
|
||||||
|
SALS.nelts is not 1 is when we set a breakpoint on an overloaded
|
||||||
|
function. In that case, it's still not possible to specify
|
||||||
|
separate conditions for different overloaded functions, so
|
||||||
|
we take just a single condition string.
|
||||||
|
|
||||||
|
The parameter PENDING_BP points to a pending breakpoint that is
|
||||||
|
the basis of the breakpoints currently being created. The pending
|
||||||
|
breakpoint may contain a separate condition string or commands
|
||||||
|
that were added after the initial pending breakpoint was created.
|
||||||
|
|
||||||
|
NOTE: If the function succeeds, the caller is expected to cleanup
|
||||||
|
the arrays ADDR_STRING, COND_STRING, 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
|
||||||
|
create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
|
||||||
|
char *cond_string,
|
||||||
|
enum bptype type, enum bpdisp disposition,
|
||||||
|
int thread, int ignore_count, int from_tty,
|
||||||
|
struct breakpoint *pending_bp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sals.nelts; ++i)
|
||||||
|
{
|
||||||
|
create_breakpoint (sals.sals[i], addr_string[i],
|
||||||
|
cond_string, type, disposition,
|
||||||
|
thread, ignore_count, from_tty,
|
||||||
|
pending_bp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse ARG which is assumed to be a SAL specification possibly
|
/* Parse ARG which is assumed to be a SAL specification possibly
|
||||||
@ -5192,6 +5224,59 @@ do_captured_parse_breakpoint (struct ui_out *ui, void *data)
|
|||||||
args->not_found_ptr);
|
args->not_found_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given TOK, a string specification of condition and thread, as
|
||||||
|
accepted by the 'break' command, extract the condition
|
||||||
|
string and thread number and set *COND_STRING and *THREAD.
|
||||||
|
PC identifies the context at which the condition should be parsed.
|
||||||
|
If no condition is found, *COND_STRING is set to NULL.
|
||||||
|
If no thread is found, *THREAD is set to -1. */
|
||||||
|
static void
|
||||||
|
find_condition_and_thread (char *tok, CORE_ADDR pc,
|
||||||
|
char **cond_string, int *thread)
|
||||||
|
{
|
||||||
|
*cond_string = NULL;
|
||||||
|
*thread = -1;
|
||||||
|
while (tok && *tok)
|
||||||
|
{
|
||||||
|
char *end_tok;
|
||||||
|
int toklen;
|
||||||
|
char *cond_start = NULL;
|
||||||
|
char *cond_end = NULL;
|
||||||
|
while (*tok == ' ' || *tok == '\t')
|
||||||
|
tok++;
|
||||||
|
|
||||||
|
end_tok = tok;
|
||||||
|
|
||||||
|
while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
|
||||||
|
end_tok++;
|
||||||
|
|
||||||
|
toklen = end_tok - tok;
|
||||||
|
|
||||||
|
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
|
||||||
|
{
|
||||||
|
tok = cond_start = end_tok + 1;
|
||||||
|
parse_exp_1 (&tok, block_for_pc (pc), 0);
|
||||||
|
cond_end = tok;
|
||||||
|
*cond_string = savestring (cond_start,
|
||||||
|
cond_end - cond_start);
|
||||||
|
}
|
||||||
|
else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
|
||||||
|
{
|
||||||
|
char *tmptok;
|
||||||
|
|
||||||
|
tok = end_tok + 1;
|
||||||
|
tmptok = tok;
|
||||||
|
*thread = strtol (tok, &tok, 0);
|
||||||
|
if (tok == tmptok)
|
||||||
|
error (_("Junk after thread keyword."));
|
||||||
|
if (!valid_thread_id (*thread))
|
||||||
|
error (_("Unknown thread %d."), *thread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error (_("Junk at end of arguments."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set a breakpoint according to ARG (function, linenum or *address)
|
/* Set a breakpoint according to ARG (function, linenum or *address)
|
||||||
flag: first bit : 0 non-temporary, 1 temporary.
|
flag: first bit : 0 non-temporary, 1 temporary.
|
||||||
second bit : 0 normal breakpoint, 1 hardware breakpoint.
|
second bit : 0 normal breakpoint, 1 hardware breakpoint.
|
||||||
@ -5205,9 +5290,8 @@ break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_b
|
|||||||
struct gdb_exception e;
|
struct gdb_exception e;
|
||||||
int tempflag, hardwareflag;
|
int tempflag, hardwareflag;
|
||||||
struct symtabs_and_lines sals;
|
struct symtabs_and_lines sals;
|
||||||
struct expression **cond = 0;
|
|
||||||
struct symtab_and_line pending_sal;
|
struct symtab_and_line pending_sal;
|
||||||
char **cond_string = (char **) NULL;
|
char *cond_string = NULL;
|
||||||
char *copy_arg;
|
char *copy_arg;
|
||||||
char *err_msg;
|
char *err_msg;
|
||||||
char *addr_start = arg;
|
char *addr_start = arg;
|
||||||
@ -5297,14 +5381,6 @@ break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_b
|
|||||||
make_cleanup (xfree, addr_string);
|
make_cleanup (xfree, addr_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate space for all the cond expressions. */
|
|
||||||
cond = xcalloc (sals.nelts, sizeof (struct expression *));
|
|
||||||
make_cleanup (xfree, cond);
|
|
||||||
|
|
||||||
/* Allocate space for all the cond strings. */
|
|
||||||
cond_string = xcalloc (sals.nelts, sizeof (char **));
|
|
||||||
make_cleanup (xfree, cond_string);
|
|
||||||
|
|
||||||
/* ----------------------------- SNIP -----------------------------
|
/* ----------------------------- SNIP -----------------------------
|
||||||
Anything added to the cleanup chain beyond this point is assumed
|
Anything added to the cleanup chain beyond this point is assumed
|
||||||
to be part of a breakpoint. If the breakpoint create succeeds
|
to be part of a breakpoint. If the breakpoint create succeeds
|
||||||
@ -5328,56 +5404,16 @@ break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_b
|
|||||||
/* Verify that condition can be parsed, before setting any
|
/* Verify that condition can be parsed, before setting any
|
||||||
breakpoints. Allocate a separate condition expression for each
|
breakpoints. Allocate a separate condition expression for each
|
||||||
breakpoint. */
|
breakpoint. */
|
||||||
thread = -1; /* No specific thread yet */
|
|
||||||
if (!pending)
|
if (!pending)
|
||||||
{
|
{
|
||||||
for (i = 0; i < sals.nelts; i++)
|
/* Here we only parse 'arg' to separate condition
|
||||||
{
|
from thread number, so parsing in context of first
|
||||||
char *tok = arg;
|
sal is OK. When setting the breakpoint we'll
|
||||||
while (tok && *tok)
|
re-parse it in context of each sal. */
|
||||||
{
|
find_condition_and_thread (arg, sals.sals[0].pc, &cond_string, &thread);
|
||||||
char *end_tok;
|
if (cond_string)
|
||||||
int toklen;
|
make_cleanup (xfree, cond_string);
|
||||||
char *cond_start = NULL;
|
create_breakpoints (sals, addr_string, cond_string,
|
||||||
char *cond_end = NULL;
|
|
||||||
while (*tok == ' ' || *tok == '\t')
|
|
||||||
tok++;
|
|
||||||
|
|
||||||
end_tok = tok;
|
|
||||||
|
|
||||||
while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
|
|
||||||
end_tok++;
|
|
||||||
|
|
||||||
toklen = end_tok - tok;
|
|
||||||
|
|
||||||
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
|
|
||||||
{
|
|
||||||
tok = cond_start = end_tok + 1;
|
|
||||||
cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc),
|
|
||||||
0);
|
|
||||||
make_cleanup (xfree, cond[i]);
|
|
||||||
cond_end = tok;
|
|
||||||
cond_string[i] = savestring (cond_start,
|
|
||||||
cond_end - cond_start);
|
|
||||||
make_cleanup (xfree, cond_string[i]);
|
|
||||||
}
|
|
||||||
else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
|
|
||||||
{
|
|
||||||
char *tmptok;
|
|
||||||
|
|
||||||
tok = end_tok + 1;
|
|
||||||
tmptok = tok;
|
|
||||||
thread = strtol (tok, &tok, 0);
|
|
||||||
if (tok == tmptok)
|
|
||||||
error (_("Junk after thread keyword."));
|
|
||||||
if (!valid_thread_id (thread))
|
|
||||||
error (_("Unknown thread %d."), thread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
error (_("Junk at end of arguments."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
create_breakpoints (sals, addr_string, cond, cond_string,
|
|
||||||
hardwareflag ? bp_hardware_breakpoint
|
hardwareflag ? bp_hardware_breakpoint
|
||||||
: bp_breakpoint,
|
: bp_breakpoint,
|
||||||
tempflag ? disp_del : disp_donttouch,
|
tempflag ? disp_del : disp_donttouch,
|
||||||
@ -5398,10 +5434,10 @@ break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_b
|
|||||||
: bp_breakpoint);
|
: bp_breakpoint);
|
||||||
set_breakpoint_count (breakpoint_count + 1);
|
set_breakpoint_count (breakpoint_count + 1);
|
||||||
b->number = breakpoint_count;
|
b->number = breakpoint_count;
|
||||||
b->loc->cond = *cond;
|
b->loc->cond = NULL;
|
||||||
b->thread = thread;
|
b->thread = thread;
|
||||||
b->addr_string = *addr_string;
|
b->addr_string = addr_string[0];
|
||||||
b->cond_string = *cond_string;
|
b->cond_string = cond_string;
|
||||||
b->ignore_count = ignore_count;
|
b->ignore_count = ignore_count;
|
||||||
b->pending = 1;
|
b->pending = 1;
|
||||||
b->disposition = tempflag ? disp_del : disp_donttouch;
|
b->disposition = tempflag ? disp_del : disp_donttouch;
|
||||||
@ -5445,7 +5481,7 @@ do_captured_breakpoint (struct ui_out *uiout, void *data)
|
|||||||
struct cleanup *breakpoint_chain = NULL;
|
struct cleanup *breakpoint_chain = NULL;
|
||||||
int i;
|
int i;
|
||||||
char **addr_string;
|
char **addr_string;
|
||||||
char **cond_string;
|
char *cond_string;
|
||||||
|
|
||||||
char *address_end;
|
char *address_end;
|
||||||
|
|
||||||
@ -5502,22 +5538,13 @@ do_captured_breakpoint (struct ui_out *uiout, void *data)
|
|||||||
/* Resolve all line numbers to PC's. */
|
/* Resolve all line numbers to PC's. */
|
||||||
breakpoint_sals_to_pc (&sals, args->address);
|
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)
|
if (args->condition != NULL)
|
||||||
{
|
{
|
||||||
char *tok = args->condition;
|
cond_string = xstrdup (args->condition);
|
||||||
cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
|
make_cleanup (xfree, cond_string);
|
||||||
if (*tok != '\0')
|
|
||||||
error (_("Garbage %s follows condition"), tok);
|
|
||||||
make_cleanup (xfree, cond[i]);
|
|
||||||
cond_string[i] = xstrdup (args->condition);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_breakpoints (sals, addr_string, cond, cond_string,
|
create_breakpoints (sals, addr_string, args->condition,
|
||||||
args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
|
args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
|
||||||
args->tempflag ? disp_del : disp_donttouch,
|
args->tempflag ? disp_del : disp_donttouch,
|
||||||
args->thread, args->ignore_count, 0/*from-tty*/,
|
args->thread, args->ignore_count, 0/*from-tty*/,
|
||||||
|
Loading…
Reference in New Issue
Block a user