From 9355b391f352eb72e397d06c5a0e27308363988f Mon Sep 17 00:00:00 2001 From: Stan Shebs Date: Thu, 4 Mar 2010 00:32:50 +0000 Subject: [PATCH] 2010-03-03 Stan Shebs * remote.c (remote_download_tracepoint): Iterate over locations. * tracepoint.c (validate_actionline): Ditto. (encode_actions): Add location argument. (trace_dump_command): Check all locations to see if stepping frame. --- gdb/ChangeLog | 8 +++ gdb/remote.c | 192 ++++++++++++++++++++++++++++--------------------------- gdb/tracepoint.c | 130 +++++++++++++++++++++---------------- 3 files changed, 182 insertions(+), 148 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b78e7b0..46010bd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2010-03-03 Stan Shebs + + * remote.c (remote_download_tracepoint): Iterate over locations. + * tracepoint.c (validate_actionline): Ditto. + (encode_actions): Add location argument. + (trace_dump_command): Check all locations to see if stepping + frame. + 2010-03-03 H.J. Lu Eli Zaretskii diff --git a/gdb/remote.c b/gdb/remote.c index 7f8ec58..4b11060 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -72,8 +72,8 @@ static char *target_buf; static long target_buf_size; /*static*/ void -encode_actions (struct breakpoint *t, char ***tdp_actions, - char ***stepping_actions); +encode_actions (struct breakpoint *t, struct bp_location *tloc, + char ***tdp_actions, char ***stepping_actions); /* The size to align memory write packets, when practical. The protocol does not guarantee any alignment, and gdb will generate short @@ -9253,6 +9253,7 @@ free_actions_list (char **actions_list) static void remote_download_tracepoint (struct breakpoint *t) { + struct bp_location *loc; CORE_ADDR tpaddr; char tmp[40]; char buf[2048]; @@ -9264,111 +9265,116 @@ remote_download_tracepoint (struct breakpoint *t) struct cleanup *aexpr_chain = NULL; char *pkt; - encode_actions (t, &tdp_actions, &stepping_actions); - old_chain = make_cleanup (free_actions_list_cleanup_wrapper, - tdp_actions); - (void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions); - - tpaddr = t->loc->address; - sprintf_vma (tmp, (t->loc ? tpaddr : 0)); - sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, - tmp, /* address */ - (t->enable_state == bp_enabled ? 'E' : 'D'), - t->step_count, t->pass_count); - /* Fast tracepoints are mostly handled by the target, but we can - tell the target how big of an instruction block should be moved - around. */ - if (t->type == bp_fast_tracepoint) - { - /* Only test for support at download time; we may not know - target capabilities at definition time. */ - if (remote_supports_fast_tracepoints ()) + /* Iterate over all the tracepoint locations. It's up to the target to + notice multiple tracepoint packets with the same number but different + addresses, and treat them as multiple locations. */ + for (loc = t->loc; loc; loc = loc->next) + { + encode_actions (t, loc, &tdp_actions, &stepping_actions); + old_chain = make_cleanup (free_actions_list_cleanup_wrapper, + tdp_actions); + (void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions); + + tpaddr = loc->address; + sprintf_vma (tmp, (loc ? tpaddr : 0)); + sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, + tmp, /* address */ + (t->enable_state == bp_enabled ? 'E' : 'D'), + t->step_count, t->pass_count); + /* Fast tracepoints are mostly handled by the target, but we can + tell the target how big of an instruction block should be moved + around. */ + if (t->type == bp_fast_tracepoint) { - int isize; + /* Only test for support at download time; we may not know + target capabilities at definition time. */ + if (remote_supports_fast_tracepoints ()) + { + int isize; - if (gdbarch_fast_tracepoint_valid_at (target_gdbarch, - tpaddr, &isize, NULL)) - sprintf (buf + strlen (buf), ":F%x", isize); + if (gdbarch_fast_tracepoint_valid_at (target_gdbarch, + tpaddr, &isize, NULL)) + sprintf (buf + strlen (buf), ":F%x", isize); + else + /* If it passed validation at definition but fails now, + something is very wrong. */ + internal_error (__FILE__, __LINE__, + "Fast tracepoint not valid during download"); + } else - /* If it passed validation at definition but fails now, - something is very wrong. */ - internal_error (__FILE__, __LINE__, - "Fast tracepoint not valid during download"); + /* Fast tracepoints are functionally identical to regular + tracepoints, so don't take lack of support as a reason to + give up on the trace run. */ + warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number); } - else - /* Fast tracepoints are functionally identical to regular - tracepoints, so don't take lack of support as a reason to - give up on the trace run. */ - warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number); - } - /* If the tracepoint has a conditional, make it into an agent - expression and append to the definition. */ - if (t->loc->cond) - { - /* Only test support at download time, we may not know target - capabilities at definition time. */ - if (remote_supports_cond_tracepoints ()) + /* If the tracepoint has a conditional, make it into an agent + expression and append to the definition. */ + if (loc->cond) { - aexpr = gen_eval_for_expr (t->loc->address, t->loc->cond); - aexpr_chain = make_cleanup_free_agent_expr (aexpr); - sprintf (buf + strlen (buf), ":X%x,", aexpr->len); - pkt = buf + strlen (buf); - for (ndx = 0; ndx < aexpr->len; ++ndx) - pkt = pack_hex_byte (pkt, aexpr->buf[ndx]); - *pkt = '\0'; - do_cleanups (aexpr_chain); + /* Only test support at download time, we may not know target + capabilities at definition time. */ + if (remote_supports_cond_tracepoints ()) + { + aexpr = gen_eval_for_expr (tpaddr, loc->cond); + aexpr_chain = make_cleanup_free_agent_expr (aexpr); + sprintf (buf + strlen (buf), ":X%x,", aexpr->len); + pkt = buf + strlen (buf); + for (ndx = 0; ndx < aexpr->len; ++ndx) + pkt = pack_hex_byte (pkt, aexpr->buf[ndx]); + *pkt = '\0'; + do_cleanups (aexpr_chain); + } + else + warning (_("Target does not support conditional tracepoints, ignoring tp %d cond"), t->number); } - else - warning (_("Target does not support conditional tracepoints, ignoring tp %d cond"), t->number); - } - if (t->actions || *default_collect) - strcat (buf, "-"); - putpkt (buf); - remote_get_noisy_reply (&target_buf, &target_buf_size); - if (strcmp (target_buf, "OK")) - error (_("Target does not support tracepoints.")); + if (t->actions || *default_collect) + strcat (buf, "-"); + putpkt (buf); + remote_get_noisy_reply (&target_buf, &target_buf_size); + if (strcmp (target_buf, "OK")) + error (_("Target does not support tracepoints.")); - if (!t->actions && !*default_collect) - return; + if (!t->actions && !*default_collect) + continue; - /* do_single_steps (t); */ - if (tdp_actions) - { - for (ndx = 0; tdp_actions[ndx]; ndx++) + /* do_single_steps (t); */ + if (tdp_actions) { - QUIT; /* allow user to bail out with ^C */ - sprintf (buf, "QTDP:-%x:%s:%s%c", - t->number, tmp, /* address */ - tdp_actions[ndx], - ((tdp_actions[ndx + 1] || stepping_actions) - ? '-' : 0)); - putpkt (buf); - remote_get_noisy_reply (&target_buf, - &target_buf_size); - if (strcmp (target_buf, "OK")) - error (_("Error on target while setting tracepoints.")); + for (ndx = 0; tdp_actions[ndx]; ndx++) + { + QUIT; /* allow user to bail out with ^C */ + sprintf (buf, "QTDP:-%x:%s:%s%c", + t->number, tmp, /* address */ + tdp_actions[ndx], + ((tdp_actions[ndx + 1] || stepping_actions) + ? '-' : 0)); + putpkt (buf); + remote_get_noisy_reply (&target_buf, + &target_buf_size); + if (strcmp (target_buf, "OK")) + error (_("Error on target while setting tracepoints.")); + } } - } - if (stepping_actions) - { - for (ndx = 0; stepping_actions[ndx]; ndx++) + if (stepping_actions) { - QUIT; /* allow user to bail out with ^C */ - sprintf (buf, "QTDP:-%x:%s:%s%s%s", - t->number, tmp, /* address */ - ((ndx == 0) ? "S" : ""), - stepping_actions[ndx], - (stepping_actions[ndx + 1] ? "-" : "")); - putpkt (buf); - remote_get_noisy_reply (&target_buf, - &target_buf_size); - if (strcmp (target_buf, "OK")) - error (_("Error on target while setting tracepoints.")); + for (ndx = 0; stepping_actions[ndx]; ndx++) + { + QUIT; /* allow user to bail out with ^C */ + sprintf (buf, "QTDP:-%x:%s:%s%s%s", + t->number, tmp, /* address */ + ((ndx == 0) ? "S" : ""), + stepping_actions[ndx], + (stepping_actions[ndx + 1] ? "-" : "")); + putpkt (buf); + remote_get_noisy_reply (&target_buf, + &target_buf_size); + if (strcmp (target_buf, "OK")) + error (_("Error on target while setting tracepoints.")); + } } + do_cleanups (old_chain); } - do_cleanups (old_chain); - return; } static void diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 1d2785f..d248db4 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -625,7 +625,8 @@ validate_actionline (char **line, struct breakpoint *t) struct cmd_list_element *c; struct expression *exp = NULL; struct cleanup *old_chain = NULL; - char *p; + char *p, *tmp_p; + struct bp_location *loc; /* if EOF is typed, *line is NULL */ if (*line == NULL) @@ -671,48 +672,53 @@ validate_actionline (char **line, struct breakpoint *t) } /* else fall thru, treat p as an expression and parse it! */ } - exp = parse_exp_1 (&p, block_for_pc (t->loc->address), 1); - old_chain = make_cleanup (free_current_contents, &exp); - - if (exp->elts[0].opcode == OP_VAR_VALUE) + tmp_p = p; + for (loc = t->loc; loc; loc = loc->next) { - if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST) - { - warning (_("constant %s (value %ld) will not be collected."), - SYMBOL_PRINT_NAME (exp->elts[2].symbol), - SYMBOL_VALUE (exp->elts[2].symbol)); - return BADLINE; - } - else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT) + p = tmp_p; + exp = parse_exp_1 (&p, block_for_pc (loc->address), 1); + old_chain = make_cleanup (free_current_contents, &exp); + + if (exp->elts[0].opcode == OP_VAR_VALUE) { - warning (_("%s is optimized away and cannot be collected."), - SYMBOL_PRINT_NAME (exp->elts[2].symbol)); - return BADLINE; + if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST) + { + warning (_("constant %s (value %ld) will not be collected."), + SYMBOL_PRINT_NAME (exp->elts[2].symbol), + SYMBOL_VALUE (exp->elts[2].symbol)); + return BADLINE; + } + else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT) + { + warning (_("%s is optimized away and cannot be collected."), + SYMBOL_PRINT_NAME (exp->elts[2].symbol)); + return BADLINE; + } } - } - /* We have something to collect, make sure that the expr to - bytecode translator can handle it and that it's not too - long. */ - aexpr = gen_trace_for_expr (t->loc->address, exp); - make_cleanup_free_agent_expr (aexpr); + /* We have something to collect, make sure that the expr to + bytecode translator can handle it and that it's not too + long. */ + aexpr = gen_trace_for_expr (loc->address, exp); + make_cleanup_free_agent_expr (aexpr); - if (aexpr->len > MAX_AGENT_EXPR_LEN) - error (_("expression too complicated, try simplifying")); + if (aexpr->len > MAX_AGENT_EXPR_LEN) + error (_("expression too complicated, try simplifying")); - ax_reqs (aexpr, &areqs); - (void) make_cleanup (xfree, areqs.reg_mask); + ax_reqs (aexpr, &areqs); + (void) make_cleanup (xfree, areqs.reg_mask); - if (areqs.flaw != agent_flaw_none) - error (_("malformed expression")); + if (areqs.flaw != agent_flaw_none) + error (_("malformed expression")); - if (areqs.min_height < 0) - error (_("gdb: Internal error: expression has min height < 0")); + if (areqs.min_height < 0) + error (_("gdb: Internal error: expression has min height < 0")); - if (areqs.max_height > 20) - error (_("expression too complicated, try simplifying")); + if (areqs.max_height > 20) + error (_("expression too complicated, try simplifying")); - do_cleanups (old_chain); + do_cleanups (old_chain); + } } while (p && *p++ == ','); return GENERIC; @@ -727,20 +733,25 @@ validate_actionline (char **line, struct breakpoint *t) while (isspace ((int) *p)) p++; - /* Only expressions are allowed for this action. */ - exp = parse_exp_1 (&p, block_for_pc (t->loc->address), 1); - old_chain = make_cleanup (free_current_contents, &exp); + tmp_p = p; + for (loc = t->loc; loc; loc = loc->next) + { + p = tmp_p; + /* Only expressions are allowed for this action. */ + exp = parse_exp_1 (&p, block_for_pc (loc->address), 1); + old_chain = make_cleanup (free_current_contents, &exp); - /* We have something to evaluate, make sure that the expr to - bytecode translator can handle it and that it's not too - long. */ - aexpr = gen_eval_for_expr (t->loc->address, exp); - make_cleanup_free_agent_expr (aexpr); + /* We have something to evaluate, make sure that the expr to + bytecode translator can handle it and that it's not too + long. */ + aexpr = gen_eval_for_expr (loc->address, exp); + make_cleanup_free_agent_expr (aexpr); - if (aexpr->len > MAX_AGENT_EXPR_LEN) - error (_("expression too complicated, try simplifying")); + if (aexpr->len > MAX_AGENT_EXPR_LEN) + error (_("expression too complicated, try simplifying")); - do_cleanups (old_chain); + do_cleanups (old_chain); + } } while (p && *p++ == ','); return GENERIC; @@ -1238,8 +1249,8 @@ stringify_collection_list (struct collection_list *list, char *string) /* Render all actions into gdb protocol. */ /*static*/ void -encode_actions (struct breakpoint *t, char ***tdp_actions, - char ***stepping_actions) +encode_actions (struct breakpoint *t, struct bp_location *tloc, + char ***tdp_actions, char ***stepping_actions) { static char tdp_buff[2048], step_buff[2048]; char *action_exp; @@ -1263,7 +1274,7 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, *stepping_actions = NULL; gdbarch_virtual_frame_pointer (t->gdbarch, - t->loc->address, &frame_reg, &frame_offset); + tloc->address, &frame_reg, &frame_offset); action = t->actions; @@ -1322,7 +1333,7 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, { add_local_symbols (collect, t->gdbarch, - t->loc->address, + tloc->address, frame_reg, frame_offset, 'A'); @@ -1332,7 +1343,7 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, { add_local_symbols (collect, t->gdbarch, - t->loc->address, + tloc->address, frame_reg, frame_offset, 'L'); @@ -1346,7 +1357,7 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, struct agent_reqs areqs; exp = parse_exp_1 (&action_exp, - block_for_pc (t->loc->address), 1); + block_for_pc (tloc->address), 1); old_chain = make_cleanup (free_current_contents, &exp); switch (exp->elts[0].opcode) @@ -1381,11 +1392,11 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, t->gdbarch, frame_reg, frame_offset, - t->loc->address); + tloc->address); break; default: /* full-fledged expression */ - aexpr = gen_trace_for_expr (t->loc->address, exp); + aexpr = gen_trace_for_expr (tloc->address, exp); old_chain1 = make_cleanup_free_agent_expr (aexpr); @@ -1443,10 +1454,10 @@ encode_actions (struct breakpoint *t, char ***tdp_actions, struct agent_reqs areqs; exp = parse_exp_1 (&action_exp, - block_for_pc (t->loc->address), 1); + block_for_pc (tloc->address), 1); old_chain = make_cleanup (free_current_contents, &exp); - aexpr = gen_eval_for_expr (t->loc->address, exp); + aexpr = gen_eval_for_expr (tloc->address, exp); old_chain1 = make_cleanup_free_agent_expr (aexpr); ax_reqs (aexpr, &areqs); @@ -2224,6 +2235,7 @@ trace_dump_command (char *args, int from_tty) struct cleanup *old_cleanups; int stepping_actions = 0; int stepping_frame = 0; + struct bp_location *loc; if (tracepoint_number == -1) { @@ -2249,7 +2261,14 @@ trace_dump_command (char *args, int from_tty) regcache = get_current_regcache (); gdbarch = get_regcache_arch (regcache); - stepping_frame = (t->loc->address != (regcache_read_pc (regcache))); + /* If the traceframe's address matches any of the tracepoint's + locations, assume it is a direct hit rather than a while-stepping + frame. (FIXME this is not reliable, should record each frame's + type.) */ + stepping_frame = 1; + for (loc = t->loc; loc; loc = loc->next) + if (loc->address == regcache_read_pc (regcache)) + stepping_frame = 0; for (action = t->actions; action; action = action->next) { @@ -3239,6 +3258,7 @@ tfile_get_traceframe_address (off_t tframe_offset) error (_("Premature end of file while reading trace file")); tp = get_tracepoint_by_number_on_target (tpnum); + /* FIXME this is a poor heuristic if multiple locations */ if (tp && tp->loc) addr = tp->loc->address; -- 2.7.4