mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 06:45:56 +08:00
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.
This commit is contained in:
75
gdb/target.c
75
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user