public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more)
  2018-12-14 19:12 [PATCH 0/3] Fix a few leaks found by Coverity Pedro Alves
@ 2018-12-14 19:12 ` Pedro Alves
  2018-12-14 23:08   ` Simon Marchi
  2018-12-14 19:12 ` [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library Pedro Alves
  2018-12-14 19:12 ` [PATCH 1/3] Fix leak in mdebugread.c Pedro Alves
  2 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2018-12-14 19:12 UTC (permalink / raw)
  To: gdb-patches

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.  Let me know if you have a strong
preference otherwise.

gdb/ChangeLog:
2018-12-14  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.
---
 gdb/breakpoint.c      |  6 +++---
 gdb/ctf.c             | 30 +++++++++++++++++-------------
 gdb/tracefile-tfile.c | 21 +++++++++++----------
 gdb/tracepoint.c      | 24 +++++++++++++-----------
 gdb/tracepoint.h      | 12 ++++++------
 5 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 8af3d54a77..4a0b8dc0dc 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -14681,7 +14681,7 @@ read_uploaded_action (void)
 
   if (next_cmd < this_utp->cmd_strings.size ())
     {
-      rslt = this_utp->cmd_strings[next_cmd];
+      rslt = this_utp->cmd_strings[next_cmd].get ();
       next_cmd++;
     }
 
@@ -14702,7 +14702,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
   struct tracepoint *tp;
 
   if (utp->at_string)
-    addr_str = utp->at_string;
+    addr_str = utp->at_string.get ();
   else
     {
       /* In the absence of a source location, fall back to raw
@@ -14726,7 +14726,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
 							 current_language);
   if (!create_breakpoint (get_current_arch (),
 			  location.get (),
-			  utp->cond_string, -1, addr_str,
+			  utp->cond_string.get (), -1, addr_str,
 			  0 /* parse cond/thread */,
 			  0 /* tempflag */,
 			  utp->type /* type_wanted */,
diff --git a/gdb/ctf.c b/gdb/ctf.c
index ca5266fbd7..e98fb9c1ba 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -596,38 +596,42 @@ ctf_write_uploaded_tp (struct trace_file_writer *self,
 
   /* condition  */
   if (tp->cond != NULL)
-    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond));
+    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
+		    strlen (tp->cond.get ()));
   ctf_save_write (&writer->tcs, &zero, 1);
 
   /* actions */
   u32 = tp->actions.size ();
   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
-  for (char *act : tp->actions)
-    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
+  for (auto &&act : tp->actions)
+    ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
+		    strlen (act.get ()) + 1);
 
   /* step_actions */
   u32 = tp->step_actions.size ();
   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
-  for (char *act : tp->step_actions)
-    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
+  for (auto &&act : tp->step_actions)
+    ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
+		    strlen (act.get ()) + 1);
 
   /* at_string */
   if (tp->at_string != NULL)
-    ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string,
-		    strlen (tp->at_string));
+    ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string.get (),
+		    strlen (tp->at_string.get ()));
   ctf_save_write (&writer->tcs, &zero, 1);
 
   /* cond_string */
   if (tp->cond_string != NULL)
-    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string,
-		    strlen (tp->cond_string));
+    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string.get (),
+		    strlen (tp->cond_string.get ()));
   ctf_save_write (&writer->tcs, &zero, 1);
 
   /* cmd_strings */
   u32 = tp->cmd_strings.size ();
   ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
-  for (char *act : tp->cmd_strings)
-    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
+  for (auto &&act : tp->cmd_strings)
+    ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
+		    strlen (act.get ()) + 1);
 
 }
 
@@ -1023,7 +1027,7 @@ ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
 	  const struct bt_definition *element				\
 	    = bt_ctf_get_index ((EVENT), def, i);			\
 									\
-	  (VAR)->ARRAY.push_back					\
+	  (VAR)->ARRAY.emplace_back					\
 	    (xstrdup (bt_ctf_get_string (element)));			\
 	}								\
     }									\
@@ -1040,7 +1044,7 @@ ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
 							   #FIELD));	\
 									\
       if (strlen (p) > 0)						\
-	(VAR)->FIELD = xstrdup (p);					\
+	(VAR)->FIELD.reset (xstrdup (p));				\
       else								\
 	(VAR)->FIELD = NULL;						\
     }									\
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index 6996e3d1e5..8e8cb15fd4 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -262,31 +262,32 @@ tfile_write_uploaded_tp (struct trace_file_writer *self,
     fprintf (writer->fp, ":F%x", utp->orig_size);
   if (utp->cond)
     fprintf (writer->fp,
-	     ":X%x,%s", (unsigned int) strlen (utp->cond) / 2,
-	     utp->cond);
+	     ":X%x,%s", (unsigned int) strlen (utp->cond.get ()) / 2,
+	     utp->cond.get ());
   fprintf (writer->fp, "\n");
-  for (char *act : utp->actions)
+  for (auto &&act : utp->actions)
     fprintf (writer->fp, "tp A%x:%s:%s\n",
-	     utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
-  for (char *act : utp->step_actions)
+	     utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act.get ());
+  for (auto &&act : utp->step_actions)
     fprintf (writer->fp, "tp S%x:%s:%s\n",
-	     utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act);
+	     utp->number, phex_nz (utp->addr, sizeof (utp->addr)), act.get ());
   if (utp->at_string)
     {
       encode_source_string (utp->number, utp->addr,
-			    "at", utp->at_string, buf, MAX_TRACE_UPLOAD);
+			    "at", utp->at_string.get (),
+			    buf, MAX_TRACE_UPLOAD);
       fprintf (writer->fp, "tp Z%s\n", buf);
     }
   if (utp->cond_string)
     {
       encode_source_string (utp->number, utp->addr,
-			    "cond", utp->cond_string,
+			    "cond", utp->cond_string.get (),
 			    buf, MAX_TRACE_UPLOAD);
       fprintf (writer->fp, "tp Z%s\n", buf);
     }
-  for (char *act : utp->cmd_strings)
+  for (auto &&act : utp->cmd_strings)
     {
-      encode_source_string (utp->number, utp->addr, "cmd", act,
+      encode_source_string (utp->number, utp->addr, "cmd", act.get (),
 			    buf, MAX_TRACE_UPLOAD);
       fprintf (writer->fp, "tp Z%s\n", buf);
     }
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 8cd53374f9..4c940b0014 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -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')
     {
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index b43fbd7606..fbde53ebf4 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -178,21 +178,21 @@ struct uploaded_tp
   int orig_size = 0;
 
   /* String that is the encoded form of the tracepoint's condition.  */
-  char *cond = nullptr;
+  gdb::unique_xmalloc_ptr<char[]> cond;
 
   /* Vectors of strings that are the encoded forms of a tracepoint's
      actions.  */
-  std::vector<char *> actions;
-  std::vector<char *> step_actions;
+  std::vector<gdb::unique_xmalloc_ptr<char[]>> actions;
+  std::vector<gdb::unique_xmalloc_ptr<char[]>> step_actions;
 
   /* The original string defining the location of the tracepoint.  */
-  char *at_string = nullptr;
+  gdb::unique_xmalloc_ptr<char[]> at_string;
 
   /* The original string defining the tracepoint's condition.  */
-  char *cond_string = nullptr;
+  gdb::unique_xmalloc_ptr<char[]> cond_string;
 
   /* List of original strings defining the tracepoint's actions.  */
-  std::vector<char *> cmd_strings;
+  std::vector<gdb::unique_xmalloc_ptr<char[]>> cmd_strings;
 
   /* The tracepoint's current hit count.  */
   int hit_count = 0;
-- 
2.14.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 0/3] Fix a few leaks found by Coverity
@ 2018-12-14 19:12 Pedro Alves
  2018-12-14 19:12 ` [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more) Pedro Alves
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Pedro Alves @ 2018-12-14 19:12 UTC (permalink / raw)
  To: gdb-patches

This fixes a few leaks found by Coverity Scan.

Pedro Alves (3):
  Fix leak in mdebugread.c
  Fix leak in solib-target.c:library_list_start_library
  Fix tracepoint.c:parse_tracepoint_definition leak (and one more)

 gdb/breakpoint.c      |  6 +++---
 gdb/ctf.c             | 30 +++++++++++++++++-------------
 gdb/mdebugread.c      | 23 ++++++++++++++---------
 gdb/solib-target.c    |  3 +--
 gdb/tracefile-tfile.c | 21 +++++++++++----------
 gdb/tracepoint.c      | 24 +++++++++++++-----------
 gdb/tracepoint.h      | 12 ++++++------
 7 files changed, 65 insertions(+), 54 deletions(-)

-- 
2.14.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library
  2018-12-14 19:12 [PATCH 0/3] Fix a few leaks found by Coverity Pedro Alves
  2018-12-14 19:12 ` [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more) Pedro Alves
@ 2018-12-14 19:12 ` Pedro Alves
  2018-12-14 22:30   ` Simon Marchi
  2018-12-14 19:12 ` [PATCH 1/3] Fix leak in mdebugread.c Pedro Alves
  2 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2018-12-14 19:12 UTC (permalink / raw)
  To: gdb-patches

lm_info_target::name is nowadays std::string, so we're leaking the
result of xstrdup.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* solib-target.c (library_list_start_library): Don't xstrdup name.
---
 gdb/solib-target.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index 3c9872c116..6a395ad378 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -124,10 +124,9 @@ library_list_start_library (struct gdb_xml_parser *parser,
 {
   VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data;
   lm_info_target *item = new lm_info_target;
-  const char *name
+  item->name
     = (const char *) xml_find_attribute (attributes, "name")->value.get ();
 
-  item->name = xstrdup (name);
   VEC_safe_push (lm_info_target_p, *list, item);
 }
 
-- 
2.14.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] Fix leak in mdebugread.c
  2018-12-14 19:12 [PATCH 0/3] Fix a few leaks found by Coverity Pedro Alves
  2018-12-14 19:12 ` [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more) Pedro Alves
  2018-12-14 19:12 ` [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library Pedro Alves
@ 2018-12-14 19:12 ` Pedro Alves
  2018-12-14 22:28   ` Simon Marchi
  2 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2018-12-14 19:12 UTC (permalink / raw)
  To: gdb-patches

Coverity points out that all the "continue;" statements in the switch
case in parse_partial_symbols leak STABSTRING.  This is because we
only release STABSTRING at the end of the scope, with:

     	     	  if (stabstring
		    && stabstring != debug_info->ss + fh->issBase + sh.iss)
		  xfree (stabstring);

but that bit of code is skipped if a case in the switch statement ends
with "continue".

Fix this by using gdb::unique_xmalloc_ptr to manage the heap-allocated
version of 'stabsstring'.

I don't know how to test this.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* mdebugread.c (parse_partial_symbols): Use
	gdb::unique_xmalloc_ptr to manage heap-allocated 'stabsstring'.
---
 gdb/mdebugread.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 26687f6c8d..eddf0a68f8 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -2767,6 +2767,9 @@ parse_partial_symbols (minimal_symbol_reader &reader,
 	      /* Handle stabs continuation.  */
 	      {
 		char *stabstring = debug_info->ss + fh->issBase + sh.iss;
+		/* If we need to heap-allocate STABSTRING, this owns
+		   it.  */
+		gdb::unique_xmalloc_ptr<char> stabstring_storage;
 		int len = strlen (stabstring);
 
 		while (stabstring[len - 1] == '\\')
@@ -2789,14 +2792,19 @@ parse_partial_symbols (minimal_symbol_reader &reader,
 		    stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
 		    len2 = strlen (stabstring2);
 
-		    /* Concatinate stabstring2 with stabstring1.  */
-		    if (stabstring
-		     && stabstring != debug_info->ss + fh->issBase + sh.iss)
-		      stabstring
-			= (char *) xrealloc (stabstring, len + len2 + 1);
+		    /* Concatenate stabstring2 with stabstring1.  */
+		    if (stabstring_storage != nullptr)
+		      {
+			stabstring_storage.reset
+			  ((char *) xrealloc (stabstring_storage.release (),
+					      len + len2 + 1));
+			stabstring = stabstring_storage.get ();
+		      }
 		    else
 		      {
-			stabstring = (char *) xmalloc (len + len2 + 1);
+			stabstring_storage.reset
+			  ((char *) xmalloc (len + len2 + 1));
+			stabstring = stabstring_storage.get ();
 			strcpy (stabstring, stabstring1);
 		      }
 		    strcpy (stabstring + len, stabstring2);
@@ -3332,9 +3340,6 @@ parse_partial_symbols (minimal_symbol_reader &reader,
 			       hex_string (type_code)); /* CUR_SYMBOL_TYPE */
 		    continue;
 		  }
-		if (stabstring
-		    && stabstring != debug_info->ss + fh->issBase + sh.iss)
-		  xfree (stabstring);
 	      }
 	      /* end - Handle continuation */
 	    }
-- 
2.14.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] Fix leak in mdebugread.c
  2018-12-14 19:12 ` [PATCH 1/3] Fix leak in mdebugread.c Pedro Alves
@ 2018-12-14 22:28   ` Simon Marchi
  0 siblings, 0 replies; 8+ messages in thread
From: Simon Marchi @ 2018-12-14 22:28 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2018-12-14 14:12, Pedro Alves wrote:
> Coverity points out that all the "continue;" statements in the switch
> case in parse_partial_symbols leak STABSTRING.  This is because we
> only release STABSTRING at the end of the scope, with:
> 
>      	     	  if (stabstring
> 		    && stabstring != debug_info->ss + fh->issBase + sh.iss)
> 		  xfree (stabstring);
> 
> but that bit of code is skipped if a case in the switch statement ends
> with "continue".
> 
> Fix this by using gdb::unique_xmalloc_ptr to manage the heap-allocated
> version of 'stabsstring'.

This LGTM, AFAICT.

> I don't know how to test this.

Go back in time?

Simon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library
  2018-12-14 19:12 ` [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library Pedro Alves
@ 2018-12-14 22:30   ` Simon Marchi
  0 siblings, 0 replies; 8+ messages in thread
From: Simon Marchi @ 2018-12-14 22:30 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2018-12-14 14:12, Pedro Alves wrote:
> lm_info_target::name is nowadays std::string, so we're leaking the
> result of xstrdup.

Oops.  LGTM.

Thanks,

Simon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more)
  2018-12-14 19:12 ` [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more) Pedro Alves
@ 2018-12-14 23:08   ` Simon Marchi
  2019-01-10 18:08     ` Pedro Alves
  0 siblings, 1 reply; 8+ messages in thread
From: Simon Marchi @ 2018-12-14 23:08 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2018-12-14 14:12, Pedro Alves wrote:
> 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.  Let me know if you have a strong
> preference otherwise.

I think I've tried to fix that using std::string in the past and 
probably didn't find the result satisfactory either, so I'm fine with 
this patch.

I just have one question:

> diff --git a/gdb/ctf.c b/gdb/ctf.c
> index ca5266fbd7..e98fb9c1ba 100644
> --- a/gdb/ctf.c
> +++ b/gdb/ctf.c
> @@ -596,38 +596,42 @@ ctf_write_uploaded_tp (struct trace_file_writer 
> *self,
> 
>    /* condition  */
>    if (tp->cond != NULL)
> -    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen 
> (tp->cond));
> +    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
> +		    strlen (tp->cond.get ()));
>    ctf_save_write (&writer->tcs, &zero, 1);
> 
>    /* actions */
>    u32 = tp->actions.size ();
>    ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
> -  for (char *act : tp->actions)
> -    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
> +  for (auto &&act : tp->actions)
> +    ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
> +		    strlen (act.get ()) + 1);

Is there a reason to use "auto &&", instead of let's say "const auto &"? 
  Since we don't want to modify the unique_ptr...

I just read:

   
https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/
   
https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

and didn't immediately see why it would be useful in this situation, so 
I thought I'd ask.

Simon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more)
  2018-12-14 23:08   ` Simon Marchi
@ 2019-01-10 18:08     ` Pedro Alves
  0 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2019-01-10 18:08 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 12/14/2018 11:07 PM, Simon Marchi wrote:
> On 2018-12-14 14:12, Pedro Alves wrote:

> I just have one question:
> 
>> diff --git a/gdb/ctf.c b/gdb/ctf.c
>> index ca5266fbd7..e98fb9c1ba 100644
>> --- a/gdb/ctf.c
>> +++ b/gdb/ctf.c
>> @@ -596,38 +596,42 @@ ctf_write_uploaded_tp (struct trace_file_writer *self,
>>
>>    /* condition  */
>>    if (tp->cond != NULL)
>> -    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond, strlen (tp->cond));
>> +    ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
>> +            strlen (tp->cond.get ()));
>>    ctf_save_write (&writer->tcs, &zero, 1);
>>
>>    /* actions */
>>    u32 = tp->actions.size ();
>>    ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
>> -  for (char *act : tp->actions)
>> -    ctf_save_write (&writer->tcs, (gdb_byte *) act, strlen (act) + 1);
>> +  for (auto &&act : tp->actions)
>> +    ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
>> +            strlen (act.get ()) + 1);
> 
> Is there a reason to use "auto &&", instead of let's say "const auto &"?  Since we don't want to modify the unique_ptr...
> 
> I just read:
> 
>   https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/
>   https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
> 
> and didn't immediately see why it would be useful in this situation, so I thought I'd ask.

No reason, I had just written auto&& without thinking about
it, mainly because auto&& universally works.

I changed it to 'const auto &' and pushed in the series.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-01-10 18:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-14 19:12 [PATCH 0/3] Fix a few leaks found by Coverity Pedro Alves
2018-12-14 19:12 ` [PATCH 3/3] Fix tracepoint.c:parse_tracepoint_definition leak (and one more) Pedro Alves
2018-12-14 23:08   ` Simon Marchi
2019-01-10 18:08     ` Pedro Alves
2018-12-14 19:12 ` [PATCH 2/3] Fix leak in solib-target.c:library_list_start_library Pedro Alves
2018-12-14 22:30   ` Simon Marchi
2018-12-14 19:12 ` [PATCH 1/3] Fix leak in mdebugread.c Pedro Alves
2018-12-14 22:28   ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).