Fix tracepoint.c:parse_tracepoint_definition leak (and one more)

Coverity points out that gdb/tracepoint.c:parse_tracepoint_definition
can leak 'cond' in this line:

      cond = (char *) xmalloc (2 * xlen + 1);

That can leak because we're in a loop and 'cond' may have already been
xmalloc'ed into in a previous iteration.  That won't normally happen,
because we don't expect to see a tracepoint definition with multiple
conditions listed, but, it doesn't hurt to be pedantically correct,
in case some stub manages to send something odd back to GDB.

At first I thought I'd just replace the xmalloc call with:

      cond = (char *) xrealloc (cond, 2 * xlen + 1);

and be done with it.  However, my pedantic self realizes that
warning() can throw as well (due to pagination + Ctrl-C), so I fixed
it using gdb::unique_xmalloc_ptr instead.

While doing this, I noticed that these vectors in struct uploaded_tp:

  std::vector<char *> actions;
  std::vector<char *> step_actions;

hold heap-allocated strings, but nothing is freeing the strings,
AFAICS.

So I ended up switching all the heap-allocated strings in uploaded_tp
to unique pointers.  This patch is the result of that.

I also wrote an alternative, but similar patch that uses std::string
throughout instead of gdb::unique_xmalloc_ptr, but in the end reverted
it because the code didn't look that much better, and I kind of
dislike replacing pointers with fat std::string's (3 or 4 times the
size of a pointer) in structures.

gdb/ChangeLog:
2019-01-10  Pedro Alves  <palves@redhat.com>

	* breakpoint.c (read_uploaded_action)
	(create_tracepoint_from_upload): Adjust to use
	gdb::unique_xmalloc_ptr.
	* ctf.c (ctf_write_uploaded_tp):
	(SET_ARRAY_FIELD): Use emplace_back.
	(SET_STRING_FIELD): Adjust to use gdb::unique_xmalloc_ptr.
	* tracefile-tfile.c (tfile_write_uploaded_tp):
	* tracepoint.c (parse_tracepoint_definition): Adjust to use
	gdb::unique_xmalloc_ptr.
	* tracepoint.h (struct uploaded_tp) <cond, actions, step_actions,
	at_string, cond_string, cmd_strings>: Replace char pointers
	with gdb::unique_xmalloc_ptr.
This commit is contained in:
Pedro Alves 2019-01-10 17:52:39 +00:00
parent 2f667667e2
commit 67aa1f3c28
6 changed files with 65 additions and 43 deletions

View file

@ -3083,7 +3083,8 @@ find_matching_tracepoint_location (struct uploaded_tp *utp)
if (b->type == utp->type
&& t->step_count == utp->step
&& t->pass_count == utp->pass
&& cond_string_is_same (t->cond_string, utp->cond_string)
&& cond_string_is_same (t->cond_string,
utp->cond_string.get ())
/* FIXME also test actions. */
)
{
@ -3462,7 +3463,7 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
int enabled, end;
enum bptype type;
const char *srctype;
char *cond, *buf;
char *buf;
struct uploaded_tp *utp = NULL;
p = line;
@ -3475,13 +3476,14 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
p++; /* skip a colon */
if (piece == 'T')
{
gdb::unique_xmalloc_ptr<char[]> cond;
enabled = (*p++ == 'E');
p++; /* skip a colon */
p = unpack_varlen_hex (p, &step);
p++; /* skip a colon */
p = unpack_varlen_hex (p, &pass);
type = bp_tracepoint;
cond = NULL;
/* Thumb through optional fields. */
while (*p == ':')
{
@ -3502,8 +3504,8 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
p++;
p = unpack_varlen_hex (p, &xlen);
p++; /* skip a comma */
cond = (char *) xmalloc (2 * xlen + 1);
strncpy (cond, p, 2 * xlen);
cond.reset ((char *) xmalloc (2 * xlen + 1));
strncpy (&cond[0], p, 2 * xlen);
cond[2 * xlen] = '\0';
p += 2 * xlen;
}
@ -3516,17 +3518,17 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
utp->enabled = enabled;
utp->step = step;
utp->pass = pass;
utp->cond = cond;
utp->cond = std::move (cond);
}
else if (piece == 'A')
{
utp = get_uploaded_tp (num, addr, utpp);
utp->actions.push_back (xstrdup (p));
utp->actions.emplace_back (xstrdup (p));
}
else if (piece == 'S')
{
utp = get_uploaded_tp (num, addr, utpp);
utp->step_actions.push_back (xstrdup (p));
utp->step_actions.emplace_back (xstrdup (p));
}
else if (piece == 'Z')
{
@ -3546,11 +3548,11 @@ parse_tracepoint_definition (const char *line, struct uploaded_tp **utpp)
buf[end] = '\0';
if (startswith (srctype, "at:"))
utp->at_string = xstrdup (buf);
utp->at_string.reset (xstrdup (buf));
else if (startswith (srctype, "cond:"))
utp->cond_string = xstrdup (buf);
utp->cond_string.reset (xstrdup (buf));
else if (startswith (srctype, "cmd:"))
utp->cmd_strings.push_back (xstrdup (buf));
utp->cmd_strings.emplace_back (xstrdup (buf));
}
else if (piece == 'V')
{