Remove free_memory_read_result_vector
authorTom Tromey <tom@tromey.com>
Sat, 23 Sep 2017 17:21:58 +0000 (11:21 -0600)
committerTom Tromey <tom@tromey.com>
Sat, 30 Sep 2017 03:12:19 +0000 (21:12 -0600)
This changes read_memory_robust to return a std::vector, allowing the
removal of free_memory_read_result_vector and associated cleanups.
This patch also changes the functions it touches to be a bit more
robust with regards to deallocation; it's perhaps possible that
read_memory_robust could have leaked in some situations.

This patch is based on my earlier series to remove some MI cleanups.
Regression tested by the buildbot.

gdb/ChangeLog
2017-09-29  Tom Tromey  <tom@tromey.com>

* target.c (read_whatever_is_readable): Change type of "result".
Update.
(free_memory_read_result_vector): Remove.
(read_memory_robust): Change return type.  Update.
* mi/mi-main.c (mi_cmd_data_read_memory_bytes): Update.  Use
bin2hex, std::string.
* target.h (memory_read_result_s): Remove typedef.
(free_memory_read_result_vector): Remove.
(read_memory_robust): Return std::vector.

gdb/ChangeLog
gdb/mi/mi-main.c
gdb/target.c
gdb/target.h

index 005e366488e88daf4002a670600a133a3852af8d..ed5d20c565c46c8b405eb7bebd25f323cc4cb3ef 100644 (file)
@@ -1,3 +1,15 @@
+2017-09-29  Tom Tromey  <tom@tromey.com>
+
+       * target.c (read_whatever_is_readable): Change type of "result".
+       Update.
+       (free_memory_read_result_vector): Remove.
+       (read_memory_robust): Change return type.  Update.
+       * mi/mi-main.c (mi_cmd_data_read_memory_bytes): Update.  Use
+       bin2hex, std::string.
+       * target.h (memory_read_result_s): Remove typedef.
+       (free_memory_read_result_vector): Remove.
+       (read_memory_robust): Return std::vector.
+
 2017-09-29  Tom Tromey  <tom@tromey.com>
 
        * mi/mi-main.c (captured_mi_execute_command): Use scope_restore.
index 29acf2df0bf090b1e56060d4d6a9f9d3494b0376..4a61efdc65c464269ba3bd9aa1fccf7b97ca48d3 100644 (file)
@@ -1506,12 +1506,8 @@ mi_cmd_data_read_memory_bytes (const char *command, char **argv, int argc)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   struct ui_out *uiout = current_uiout;
-  struct cleanup *cleanups;
   CORE_ADDR addr;
   LONGEST length;
-  memory_read_result_s *read_result;
-  int ix;
-  VEC(memory_read_result_s) *result;
   long offset = 0;
   int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
   int oind = 0;
@@ -1548,40 +1544,26 @@ mi_cmd_data_read_memory_bytes (const char *command, char **argv, int argc)
   addr = parse_and_eval_address (argv[0]) + offset;
   length = atol (argv[1]);
 
-  result = read_memory_robust (current_target.beneath, addr, length);
+  std::vector<memory_read_result> result
+    = read_memory_robust (current_target.beneath, addr, length);
 
-  cleanups = make_cleanup (free_memory_read_result_vector, &result);
-
-  if (VEC_length (memory_read_result_s, result) == 0)
+  if (result.size () == 0)
     error (_("Unable to read memory."));
 
   ui_out_emit_list list_emitter (uiout, "memory");
-  for (ix = 0;
-       VEC_iterate (memory_read_result_s, result, ix, read_result);
-       ++ix)
+  for (const memory_read_result &read_result : result)
     {
       ui_out_emit_tuple tuple_emitter (uiout, NULL);
-      char *data, *p;
-      int i;
-      int alloc_len;
-
-      uiout->field_core_addr ("begin", gdbarch, read_result->begin);
-      uiout->field_core_addr ("offset", gdbarch, read_result->begin - addr);
-      uiout->field_core_addr ("end", gdbarch, read_result->end);
 
-      alloc_len = (read_result->end - read_result->begin) * 2 * unit_size + 1;
-      data = (char *) xmalloc (alloc_len);
+      uiout->field_core_addr ("begin", gdbarch, read_result.begin);
+      uiout->field_core_addr ("offset", gdbarch, read_result.begin - addr);
+      uiout->field_core_addr ("end", gdbarch, read_result.end);
 
-      for (i = 0, p = data;
-          i < ((read_result->end - read_result->begin) * unit_size);
-          ++i, p += 2)
-       {
-         sprintf (p, "%02x", read_result->data[i]);
-       }
-      uiout->field_string ("contents", data);
-      xfree (data);
+      std::string data = bin2hex (read_result.data.get (),
+                                 (read_result.end - read_result.begin)
+                                 * unit_size);
+      uiout->field_string ("contents", data.c_str ());
     }
-  do_cleanups (cleanups);
 }
 
 /* Implementation of the -data-write_memory command.
index 9abaa58152509a838cad001c0244195b9a9cb864..aded0ba34f12b697a3a89bf4d156dc0d35553f21 100644 (file)
@@ -1630,43 +1630,37 @@ static void
 read_whatever_is_readable (struct target_ops *ops,
                           const ULONGEST begin, const ULONGEST end,
                           int unit_size,
-                          VEC(memory_read_result_s) **result)
+                          std::vector<memory_read_result> *result)
 {
-  gdb_byte *buf = (gdb_byte *) xmalloc (end - begin);
   ULONGEST current_begin = begin;
   ULONGEST current_end = end;
   int forward;
-  memory_read_result_s r;
   ULONGEST xfered_len;
 
   /* If we previously failed to read 1 byte, nothing can be done here.  */
   if (end - begin <= 1)
-    {
-      xfree (buf);
-      return;
-    }
+    return;
+
+  gdb::unique_xmalloc_ptr<gdb_byte> buf ((gdb_byte *) xmalloc (end - begin));
 
   /* Check that either first or the last byte is readable, and give up
      if not.  This heuristic is meant to permit reading accessible memory
      at the boundary of accessible region.  */
   if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                          buf, begin, 1, &xfered_len) == TARGET_XFER_OK)
+                          buf.get (), begin, 1, &xfered_len) == TARGET_XFER_OK)
     {
       forward = 1;
       ++current_begin;
     }
   else if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                               buf + (end - begin) - 1, end - 1, 1,
+                               buf.get () + (end - begin) - 1, end - 1, 1,
                                &xfered_len) == TARGET_XFER_OK)
     {
       forward = 0;
       --current_end;
     }
   else
-    {
-      xfree (buf);
-      return;
-    }
+    return;
 
   /* Loop invariant is that the [current_begin, current_end) was previously
      found to be not readable as a whole.
@@ -1696,7 +1690,7 @@ read_whatever_is_readable (struct target_ops *ops,
        }
 
       xfer = target_read (ops, TARGET_OBJECT_MEMORY, NULL,
-                         buf + (first_half_begin - begin) * unit_size,
+                         buf.get () + (first_half_begin - begin) * unit_size,
                          first_half_begin,
                          first_half_end - first_half_begin);
 
@@ -1723,47 +1717,27 @@ read_whatever_is_readable (struct target_ops *ops,
   if (forward)
     {
       /* The [begin, current_begin) range has been read.  */
-      r.begin = begin;
-      r.end = current_begin;
-      r.data = buf;
+      result->emplace_back (begin, current_end, std::move (buf));
     }
   else
     {
       /* The [current_end, end) range has been read.  */
       LONGEST region_len = end - current_end;
 
-      r.data = (gdb_byte *) xmalloc (region_len * unit_size);
-      memcpy (r.data, buf + (current_end - begin) * unit_size,
+      gdb::unique_xmalloc_ptr<gdb_byte> data
+       ((gdb_byte *) xmalloc (region_len * unit_size));
+      memcpy (data.get (), buf.get () + (current_end - begin) * unit_size,
              region_len * unit_size);
-      r.begin = current_end;
-      r.end = end;
-      xfree (buf);
+      result->emplace_back (current_end, end, std::move (data));
     }
-  VEC_safe_push(memory_read_result_s, (*result), &r);
 }
 
-void
-free_memory_read_result_vector (void *x)
-{
-  VEC(memory_read_result_s) **v = (VEC(memory_read_result_s) **) x;
-  memory_read_result_s *current;
-  int ix;
-
-  for (ix = 0; VEC_iterate (memory_read_result_s, *v, ix, current); ++ix)
-    {
-      xfree (current->data);
-    }
-  VEC_free (memory_read_result_s, *v);
-}
-
-VEC(memory_read_result_s) *
+std::vector<memory_read_result>
 read_memory_robust (struct target_ops *ops,
                    const ULONGEST offset, const LONGEST len)
 {
-  VEC(memory_read_result_s) *result = 0;
+  std::vector<memory_read_result> result;
   int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
-  struct cleanup *cleanup = make_cleanup (free_memory_read_result_vector,
-                                         &result);
 
   LONGEST xfered_total = 0;
   while (xfered_total < len)
@@ -1789,19 +1763,17 @@ read_memory_robust (struct target_ops *ops,
       else
        {
          LONGEST to_read = std::min (len - xfered_total, region_len);
-         gdb_byte *buffer = (gdb_byte *) xmalloc (to_read * unit_size);
-         struct cleanup *inner_cleanup = make_cleanup (xfree, buffer);
+         gdb::unique_xmalloc_ptr<gdb_byte> buffer
+           ((gdb_byte *) xmalloc (to_read * unit_size));
 
          LONGEST xfered_partial =
-             target_read (ops, TARGET_OBJECT_MEMORY, NULL,
-                          (gdb_byte *) buffer,
+             target_read (ops, TARGET_OBJECT_MEMORY, NULL, buffer.get (),
                           offset + xfered_total, to_read);
          /* Call an observer, notifying them of the xfer progress?  */
          if (xfered_partial <= 0)
            {
              /* Got an error reading full chunk.  See if maybe we can read
                 some subrange.  */
-             do_cleanups (inner_cleanup);
              read_whatever_is_readable (ops, offset + xfered_total,
                                         offset + xfered_total + to_read,
                                         unit_size, &result);
@@ -1809,20 +1781,15 @@ read_memory_robust (struct target_ops *ops,
            }
          else
            {
-             struct memory_read_result r;
-
-             discard_cleanups (inner_cleanup);
-             r.data = buffer;
-             r.begin = offset + xfered_total;
-             r.end = r.begin + xfered_partial;
-             VEC_safe_push (memory_read_result_s, result, &r);
+             result.emplace_back (offset + xfered_total,
+                                  offset + xfered_total + xfered_partial,
+                                  std::move (buffer));
              xfered_total += xfered_partial;
            }
          QUIT;
        }
     }
 
-  discard_cleanups (cleanup);
   return result;
 }
 
index 87482dcd91cef38205e07318d40943419f6d644c..f5ad1e5ca8c4496e5130568ada1a47ae87156067 100644 (file)
@@ -287,22 +287,31 @@ extern LONGEST target_read (struct target_ops *ops,
                            ULONGEST offset, LONGEST len);
 
 struct memory_read_result
+{
+  memory_read_result (ULONGEST begin_, ULONGEST end_,
+                     gdb::unique_xmalloc_ptr<gdb_byte> &&data_)
+    : begin (begin_),
+      end (end_),
+      data (std::move (data_))
   {
-    /* First address that was read.  */
-    ULONGEST begin;
-    /* Past-the-end address.  */
-    ULONGEST end;
-    /* The data.  */
-    gdb_byte *data;
-};
-typedef struct memory_read_result memory_read_result_s;
-DEF_VEC_O(memory_read_result_s);
+  }
+
+  ~memory_read_result () = default;
+
+  memory_read_result (memory_read_result &&other) = default;
 
-extern void free_memory_read_result_vector (void *);
+  DISABLE_COPY_AND_ASSIGN (memory_read_result);
+
+  /* First address that was read.  */
+  ULONGEST begin;
+  /* Past-the-end address.  */
+  ULONGEST end;
+  /* The data.  */
+  gdb::unique_xmalloc_ptr<gdb_byte> data;
+};
 
-extern VEC(memory_read_result_s)* read_memory_robust (struct target_ops *ops,
-                                                     const ULONGEST offset,
-                                                     const LONGEST len);
+extern std::vector<memory_read_result> read_memory_robust
+    (struct target_ops *ops, const ULONGEST offset, const LONGEST len);
 
 /* Request that OPS transfer up to LEN addressable units from BUF to the
    target's OBJECT.  When writing to a memory object, the addressable unit