aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2007-09-22 19:10:05 +0000
committerVladimir Prus <vladimir@codesourcery.com>2007-09-22 19:10:05 +0000
commit018d34a46b565ceaf494bcf8f3a8a9ec488bb69a (patch)
tree63c1c6b0701791ee3024d624e59fe06d8a3d2f06
parent511a6cd4e1e2b29e79fd05f8dd3fb95de3961ed6 (diff)
downloadbinutils-018d34a46b565ceaf494bcf8f3a8a9ec488bb69a.zip
binutils-018d34a46b565ceaf494bcf8f3a8a9ec488bb69a.tar.gz
binutils-018d34a46b565ceaf494bcf8f3a8a9ec488bb69a.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/breakpoint.c313
2 files changed, 185 insertions, 144 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c3dd35e..0a6d886 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,20 @@
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
field to...
(struct bp_location): Here.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 333242a..e9b99cc 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -4984,93 +4984,125 @@ 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.
+/* Create a breakpoint with SAL as location. Use ADDR_STRING
+ as textual description of the location, and COND_STRING
+ as condition expression.
+
+ The paramter PENDING_BP is same as for the
+ create_breakpoints function. */
+
+static void
+create_breakpoint (struct symtab_and_line sal, char *addr_string,
+ char *cond_string,
+ enum bptype type, enum bpdisp disposition,
+ int thread, int ignore_count, int from_tty,
+ struct breakpoint *pending_bp)
+{
+ 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 + 1, 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."));
+ }
+
+ if (from_tty)
+ describe_other_breakpoints (sal.pc, sal.section, thread);
+
+ b = set_raw_breakpoint (sal, type);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->thread = thread;
+
+ b->cond_string = cond_string;
+ b->ignore_count = ignore_count;
+ b->enable_state = bp_enabled;
+ b->disposition = disposition;
+ /* If resolving a pending breakpoint, a check must be made to see if
+ the user has specified a new condition or commands for the
+ breakpoint. A new condition will override any condition that was
+ initially specified with the initial breakpoint command. */
+ if (pending_bp)
+ {
+ if (pending_bp->cond_string)
+ b->cond_string = savestring (pending_bp->cond_string,
+ strlen (pending_bp->cond_string));
+
+ /* If there are commands associated with the breakpoint, they should
+ be copied too. */
+ if (pending_bp->commands)
+ b->commands = copy_command_lines (pending_bp->commands);
+
+ /* We have to copy over the ignore_count and thread as well. */
+ b->ignore_count = pending_bp->ignore_count;
+ b->thread = pending_bp->thread;
+ }
+
+ 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, COND and SALS (but not the
+ 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,
- struct expression **cond, char **cond_string,
+ char *cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int ignore_count, int from_tty,
struct breakpoint *pending_bp)
{
- if (type == bp_hardware_breakpoint)
+ int i;
+ for (i = 0; i < sals.nelts; ++i)
{
- 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."));
+ create_breakpoint (sals.sals[i], addr_string[i],
+ cond_string, type, disposition,
+ thread, ignore_count, from_tty,
+ pending_bp);
}
-
- /* 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)
- describe_other_breakpoints (sal.pc, sal.section, thread);
-
- b = set_raw_breakpoint (sal, type);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->loc->cond = cond[i];
- b->thread = thread;
- if (addr_string[i])
- b->addr_string = addr_string[i];
- 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->enable_state = bp_enabled;
- b->disposition = disposition;
- /* If resolving a pending breakpoint, a check must be made to see if
- the user has specified a new condition or commands for the
- breakpoint. A new condition will override any condition that was
- initially specified with the initial breakpoint command. */
- if (pending_bp)
- {
- char *arg;
- if (pending_bp->cond_string)
- {
- arg = 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
- be copied too. */
- if (pending_bp->commands)
- b->commands = copy_command_lines (pending_bp->commands);
-
- /* We have to copy over the ignore_count and thread as well. */
- b->ignore_count = pending_bp->ignore_count;
- b->thread = pending_bp->thread;
- }
- mention (b);
- }
- }
}
/* 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);
}
+/* 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)
flag: first bit : 0 non-temporary, 1 temporary.
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;
int tempflag, hardwareflag;
struct symtabs_and_lines sals;
- struct expression **cond = 0;
struct symtab_and_line pending_sal;
- char **cond_string = (char **) NULL;
+ char *cond_string = NULL;
char *copy_arg;
char *err_msg;
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);
}
- /* 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 -----------------------------
Anything added to the cleanup chain beyond this point is assumed
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
breakpoints. Allocate a separate condition expression for each
breakpoint. */
- thread = -1; /* No specific thread yet */
if (!pending)
{
- 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++;
-
- 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,
+ /* Here we only parse 'arg' to separate condition
+ from thread number, so parsing in context of first
+ sal is OK. When setting the breakpoint we'll
+ re-parse it in context of each sal. */
+ find_condition_and_thread (arg, sals.sals[0].pc, &cond_string, &thread);
+ if (cond_string)
+ make_cleanup (xfree, cond_string);
+ create_breakpoints (sals, addr_string, cond_string,
hardwareflag ? bp_hardware_breakpoint
: bp_breakpoint,
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);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
- b->loc->cond = *cond;
+ b->loc->cond = NULL;
b->thread = thread;
- b->addr_string = *addr_string;
- b->cond_string = *cond_string;
+ b->addr_string = addr_string[0];
+ b->cond_string = cond_string;
b->ignore_count = ignore_count;
b->pending = 1;
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;
int i;
char **addr_string;
- char **cond_string;
+ char *cond_string;
char *address_end;
@@ -5502,22 +5538,13 @@ do_captured_breakpoint (struct ui_out *uiout, void *data)
/* 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)
{
- 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 (xfree, cond[i]);
- cond_string[i] = xstrdup (args->condition);
- }
+ cond_string = xstrdup (args->condition);
+ make_cleanup (xfree, cond_string);
}
- create_breakpoints (sals, addr_string, cond, cond_string,
+ create_breakpoints (sals, addr_string, args->condition,
args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
args->tempflag ? disp_del : disp_donttouch,
args->thread, args->ignore_count, 0/*from-tty*/,