diff options
author | Tom Tromey <tom@tromey.com> | 2017-09-23 11:21:58 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2017-09-29 21:12:19 -0600 |
commit | 386c8614d5e65431e977b1b20cc4642f944faca1 (patch) | |
tree | 22cdc54c0b8c61dfc6aa1da002e2fa7b2e7bdc40 /gdb/target.c | |
parent | 789c4b5ea14b0c441e6021f07503e61ccfacb427 (diff) | |
download | binutils-gdb-386c8614d5e65431e977b1b20cc4642f944faca1.tar.gz |
Remove free_memory_read_result_vector
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.
Diffstat (limited to 'gdb/target.c')
-rw-r--r-- | gdb/target.c | 75 |
1 files changed, 21 insertions, 54 deletions
diff --git a/gdb/target.c b/gdb/target.c index 9abaa581525..aded0ba34f1 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -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; } |