From: Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
To: gdb-patches@sourceware.org
Cc: uweigand@de.ibm.com
Subject: [PATCH v2 3/6] Use get_remote_packet_size in download_tracepoint
Date: Fri, 27 Jul 2018 21:03:00 -0000 [thread overview]
Message-ID: <20180727210318.2960-4-pedromfc@linux.ibm.com> (raw)
In-Reply-To: <20180727210318.2960-1-pedromfc@linux.ibm.com>
This patch changes the remote target to use the remote packet size to
build QTDP packets, and to check if there is enough room for the
packet.
I changed the function to raise an error if the packet is too small,
instead of aborting gdb (through xsnprintf). It isn't clear if gdb
will be in a consistent state with respect to the stub after this,
since it's possible that some packets will be sent but not others, and
there could be an incomplete tracepoint on the stub.
The char array used to build the packets is changed to a
gdb::char_vector and sized with the result from
get_remote_packet_size.
When checking if the buffer is large enough to hold the tracepoint
condition agent expression, the length of the expression is multiplied
by two, since it is encoded with two hex digits per expression
byte. For simplicity, I assume that the result won't overflow, which
can happen for very long condition expressions.
gdb/ChangeLog:
YYYY-MM-DD Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
* remote.c (remote_target::download_tracepoint): Remove BUF_SIZE.
Replace array buf with gdb::char_vector buf, of size
get_remote_packet_size (). Replace references to buf and BUF_SIZE
to buf.data () and buf.size (). Replace strcpy, strcat and
pack_hex_byte with snprintf. Raise errors if the buffer is too
small.
---
gdb/remote.c | 135 ++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 101 insertions(+), 34 deletions(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index e3180923ee..5c8b6861fc 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -12832,26 +12832,35 @@ remote_target::remote_download_command_source (int num, ULONGEST addr,
void
remote_target::download_tracepoint (struct bp_location *loc)
{
-#define BUF_SIZE 2048
-
CORE_ADDR tpaddr;
char addrbuf[40];
- char buf[BUF_SIZE];
std::vector<std::string> tdp_actions;
std::vector<std::string> stepping_actions;
char *pkt;
struct breakpoint *b = loc->owner;
struct tracepoint *t = (struct tracepoint *) b;
struct remote_state *rs = get_remote_state ();
+ int ret;
+ char *err_msg = _("Tracepoint packet too large for target.");
+ size_t size_left;
+
+ /* We use a buffer other than rs->buf because we'll build strings
+ across multiple statements, and other statements in between could
+ modify rs->buf. */
+ gdb::char_vector buf (get_remote_packet_size ());
encode_actions_rsp (loc, &tdp_actions, &stepping_actions);
tpaddr = loc->address;
sprintf_vma (addrbuf, tpaddr);
- xsnprintf (buf, BUF_SIZE, "QTDP:%x:%s:%c:%lx:%x", b->number,
- addrbuf, /* address */
- (b->enable_state == bp_enabled ? 'E' : 'D'),
- t->step_count, t->pass_count);
+ ret = snprintf (buf.data (), buf.size (), "QTDP:%x:%s:%c:%lx:%x",
+ b->number, addrbuf, /* address */
+ (b->enable_state == bp_enabled ? 'E' : 'D'),
+ t->step_count, t->pass_count);
+
+ if (ret < 0 || ret >= buf.size ())
+ error (err_msg);
+
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
@@ -12863,8 +12872,15 @@ remote_target::download_tracepoint (struct bp_location *loc)
{
if (gdbarch_fast_tracepoint_valid_at (loc->gdbarch, tpaddr,
NULL))
- xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
- gdb_insn_length (loc->gdbarch, tpaddr));
+ {
+ size_left = buf.size () - strlen (buf.data ());
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":F%x",
+ gdb_insn_length (loc->gdbarch, tpaddr));
+
+ if (ret < 0 || ret >= size_left)
+ error (err_msg);
+ }
else
/* If it passed validation at definition but fails now,
something is very wrong. */
@@ -12888,7 +12904,15 @@ remote_target::download_tracepoint (struct bp_location *loc)
struct static_tracepoint_marker marker;
if (target_static_tracepoint_marker_at (tpaddr, &marker))
- strcat (buf, ":S");
+ {
+ size_left = buf.size () - strlen (buf.data ());
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":F%x",
+ gdb_insn_length (loc->gdbarch, tpaddr));
+
+ if (ret < 0 || ret >= size_left)
+ error (err_msg);
+ }
else
error (_("Static tracepoint not valid during download"));
}
@@ -12906,10 +12930,26 @@ remote_target::download_tracepoint (struct bp_location *loc)
capabilities at definition time. */
if (remote_supports_cond_tracepoints ())
{
- agent_expr_up aexpr = gen_eval_for_expr (tpaddr, loc->cond.get ());
- xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
- aexpr->len);
- pkt = buf + strlen (buf);
+ agent_expr_up aexpr = gen_eval_for_expr (tpaddr,
+ loc->cond.get ());
+
+ size_left = buf.size () - strlen (buf.data ());
+
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, ":X%x,", aexpr->len);
+
+ if (ret < 0 || ret >= size_left)
+ error (err_msg);
+
+ size_left = buf.size () - strlen (buf.data ());
+
+ /* Two bytes to encode each aexpr byte, plus the terminating
+ null byte. */
+ if (aexpr->len * 2 + 1 > size_left)
+ error (err_msg);
+
+ pkt = buf.data () + strlen (buf.data ());
+
for (int ndx = 0; ndx < aexpr->len; ++ndx)
pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
*pkt = '\0';
@@ -12920,8 +12960,17 @@ remote_target::download_tracepoint (struct bp_location *loc)
}
if (b->commands || *default_collect)
- strcat (buf, "-");
- putpkt (buf);
+ {
+ size_left = buf.size () - strlen (buf.data ());
+
+ ret = snprintf (buf.data () + strlen (buf.data ()),
+ size_left, "-");
+
+ if (ret < 0 || ret >= size_left)
+ error (err_msg);
+ }
+
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
error (_("Target does not support tracepoints."));
@@ -12935,11 +12984,15 @@ remote_target::download_tracepoint (struct bp_location *loc)
bool has_more = ((action_it + 1) != tdp_actions.end ()
|| !stepping_actions.empty ());
- xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
- b->number, addrbuf, /* address */
- action_it->c_str (),
- has_more ? '-' : 0);
- putpkt (buf);
+ ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%c",
+ b->number, addrbuf, /* address */
+ action_it->c_str (),
+ has_more ? '-' : 0);
+
+ if (ret < 0 || ret >= buf.size ())
+ error (err_msg);
+
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
error (_("Error on target while setting tracepoints."));
@@ -12953,12 +13006,16 @@ remote_target::download_tracepoint (struct bp_location *loc)
bool is_first = action_it == stepping_actions.begin ();
bool has_more = (action_it + 1) != stepping_actions.end ();
- xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
- b->number, addrbuf, /* address */
- is_first ? "S" : "",
- action_it->c_str (),
- has_more ? "-" : "");
- putpkt (buf);
+ ret = snprintf (buf.data (), buf.size (), "QTDP:-%x:%s:%s%s%s",
+ b->number, addrbuf, /* address */
+ is_first ? "S" : "",
+ action_it->c_str (),
+ has_more ? "-" : "");
+
+ if (ret < 0 || ret >= buf.size ())
+ error (err_msg);
+
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
error (_("Error on target while setting tracepoints."));
@@ -12968,22 +13025,32 @@ remote_target::download_tracepoint (struct bp_location *loc)
{
if (b->location != NULL)
{
- strcpy (buf, "QTDPsrc:");
+ ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
+
+ if (ret < 0 || ret >= buf.size ())
+ error (err_msg);
+
encode_source_string (b->number, loc->address, "at",
event_location_to_string (b->location.get ()),
- buf + strlen (buf), 2048 - strlen (buf));
- putpkt (buf);
+ buf.data () + strlen (buf.data ()),
+ buf.size () - strlen (buf.data ()));
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
warning (_("Target does not support source download."));
}
if (b->cond_string)
{
- strcpy (buf, "QTDPsrc:");
+ ret = snprintf (buf.data (), buf.size (), "QTDPsrc:");
+
+ if (ret < 0 || ret >= buf.size ())
+ error (err_msg);
+
encode_source_string (b->number, loc->address,
- "cond", b->cond_string, buf + strlen (buf),
- 2048 - strlen (buf));
- putpkt (buf);
+ "cond", b->cond_string,
+ buf.data () + strlen (buf.data ()),
+ buf.size () - strlen (buf.data ()));
+ putpkt (buf.data ());
remote_get_noisy_reply ();
if (strcmp (rs->buf, "OK"))
warning (_("Target does not support source download."));
--
2.13.6
next prev parent reply other threads:[~2018-07-27 21:03 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-27 21:03 [PATCH v2 0/6] Fix tracepoint register limitations Pedro Franco de Carvalho
2018-07-27 21:03 ` Pedro Franco de Carvalho [this message]
2018-08-02 16:47 ` [PATCH v2 3/6] Use get_remote_packet_size in download_tracepoint Ulrich Weigand
2018-08-03 21:41 ` Pedro Franco de Carvalho
2018-08-06 12:40 ` Ulrich Weigand
[not found] ` <feb8623a-b89e-7519-22de-0d6ede3d5768@arm.com>
2018-08-08 10:33 ` [committed] Fix gdb/remote.c build failure Szabolcs Nagy
2018-08-08 12:25 ` Ulrich Weigand
2018-08-08 15:55 ` [PATCH v2 3/6] Use get_remote_packet_size in download_tracepoint Pedro Franco de Carvalho
2018-08-03 21:41 ` Pedro Franco de Carvalho
2018-07-27 21:03 ` [PATCH v2 5/6] Variable size for regs mask in collection list Pedro Franco de Carvalho
2018-08-02 17:01 ` Ulrich Weigand
2018-07-27 21:03 ` [PATCH v2 6/6] Allow larger regblock sizes when saving tracefiles Pedro Franco de Carvalho
2018-08-02 17:04 ` Ulrich Weigand
2018-07-27 21:03 ` [PATCH v2 2/6] Remove trailing '-' from the last QTDP action packet Pedro Franco de Carvalho
2018-08-02 16:44 ` Ulrich Weigand
2018-07-27 21:03 ` [PATCH v2 4/6] Use remote register numbers in tracepoint mask Pedro Franco de Carvalho
2018-08-02 16:58 ` Ulrich Weigand
2018-08-03 22:09 ` Pedro Franco de Carvalho
2018-08-03 22:10 ` Pedro Franco de Carvalho
2018-08-06 12:42 ` Ulrich Weigand
2018-08-06 20:18 ` Pedro Franco de Carvalho
2018-07-27 21:03 ` [PATCH v2 1/6] Fix indentation in remote_target::download_tracepoint Pedro Franco de Carvalho
2018-08-02 16:43 ` Ulrich Weigand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180727210318.2960-4-pedromfc@linux.ibm.com \
--to=pedromfc@linux.ibm.com \
--cc=gdb-patches@sourceware.org \
--cc=uweigand@de.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox