Use unique_xmalloc_ptr for read_string
This changes read_string's "buffer" out-parameter to be a unique_xmalloc_ptr, then updates the users. This allows for the removal of some cleanups. I chose unique_xmalloc_ptr rather than byte_vector here due to the way Guile unwinding seems to work. Tested by the buildbot. gdb/ChangeLog 2018-06-18 Tom Tromey <tom@tromey.com> * valprint.h (read_string): Update. * valprint.c (read_string): Change type of "buffer". (val_print_string): Update. * python/py-value.c (valpy_string): Update. * language.h (struct language_defn) <la_get_string>: Change type of "buffer". (default_get_string, c_get_string): Update. * language.c (default_get_string): Change type of "buffer". * guile/scm-value.c (gdbscm_value_to_string): Update. * c-lang.c (c_get_string): Change type of "buffer".
This commit is contained in:
parent
3f0dbd670b
commit
b4be9fadea
8 changed files with 64 additions and 55 deletions
|
@ -2096,10 +2096,10 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
|||
return (nread);
|
||||
}
|
||||
|
||||
/* Read a string from the inferior, at ADDR, with LEN characters of WIDTH bytes
|
||||
each. Fetch at most FETCHLIMIT characters. BUFFER will be set to a newly
|
||||
allocated buffer containing the string, which the caller is responsible to
|
||||
free, and BYTES_READ will be set to the number of bytes read. Returns 0 on
|
||||
/* Read a string from the inferior, at ADDR, with LEN characters of
|
||||
WIDTH bytes each. Fetch at most FETCHLIMIT characters. BUFFER
|
||||
will be set to a newly allocated buffer containing the string, and
|
||||
BYTES_READ will be set to the number of bytes read. Returns 0 on
|
||||
success, or a target_xfer_status on failure.
|
||||
|
||||
If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters
|
||||
|
@ -2122,20 +2122,18 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
|||
|
||||
int
|
||||
read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
||||
enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
|
||||
enum bfd_endian byte_order, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||
int *bytes_read)
|
||||
{
|
||||
int errcode; /* Errno returned from bad reads. */
|
||||
unsigned int nfetch; /* Chars to fetch / chars fetched. */
|
||||
gdb_byte *bufptr; /* Pointer to next available byte in
|
||||
buffer. */
|
||||
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
|
||||
|
||||
/* Loop until we either have all the characters, or we encounter
|
||||
some error, such as bumping into the end of the address space. */
|
||||
|
||||
*buffer = NULL;
|
||||
|
||||
old_chain = make_cleanup (free_current_contents, buffer);
|
||||
buffer->reset (nullptr);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
|
@ -2143,8 +2141,8 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
|||
one operation. */
|
||||
unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);
|
||||
|
||||
*buffer = (gdb_byte *) xmalloc (fetchlen * width);
|
||||
bufptr = *buffer;
|
||||
buffer->reset ((gdb_byte *) xmalloc (fetchlen * width));
|
||||
bufptr = buffer->get ();
|
||||
|
||||
nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
|
||||
/ width;
|
||||
|
@ -2173,12 +2171,12 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
|||
nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize);
|
||||
|
||||
if (*buffer == NULL)
|
||||
*buffer = (gdb_byte *) xmalloc (nfetch * width);
|
||||
buffer->reset ((gdb_byte *) xmalloc (nfetch * width));
|
||||
else
|
||||
*buffer = (gdb_byte *) xrealloc (*buffer,
|
||||
(nfetch + bufsize) * width);
|
||||
buffer->reset ((gdb_byte *) xrealloc (buffer->release (),
|
||||
(nfetch + bufsize) * width));
|
||||
|
||||
bufptr = *buffer + bufsize * width;
|
||||
bufptr = buffer->get () + bufsize * width;
|
||||
bufsize += nfetch;
|
||||
|
||||
/* Read as much as we can. */
|
||||
|
@ -2210,24 +2208,23 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
|||
}
|
||||
}
|
||||
while (errcode == 0 /* no error */
|
||||
&& bufptr - *buffer < fetchlimit * width /* no overrun */
|
||||
&& bufptr - buffer->get () < fetchlimit * width /* no overrun */
|
||||
&& !found_nul); /* haven't found NUL yet */
|
||||
}
|
||||
else
|
||||
{ /* Length of string is really 0! */
|
||||
/* We always allocate *buffer. */
|
||||
*buffer = bufptr = (gdb_byte *) xmalloc (1);
|
||||
buffer->reset ((gdb_byte *) xmalloc (1));
|
||||
bufptr = buffer->get ();
|
||||
errcode = 0;
|
||||
}
|
||||
|
||||
/* bufptr and addr now point immediately beyond the last byte which we
|
||||
consider part of the string (including a '\0' which ends the string). */
|
||||
*bytes_read = bufptr - *buffer;
|
||||
*bytes_read = bufptr - buffer->get ();
|
||||
|
||||
QUIT;
|
||||
|
||||
discard_cleanups (old_chain);
|
||||
|
||||
return errcode;
|
||||
}
|
||||
|
||||
|
@ -2793,8 +2790,7 @@ val_print_string (struct type *elttype, const char *encoding,
|
|||
int found_nul; /* Non-zero if we found the nul char. */
|
||||
unsigned int fetchlimit; /* Maximum number of chars to print. */
|
||||
int bytes_read;
|
||||
gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */
|
||||
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
|
||||
gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
|
||||
struct gdbarch *gdbarch = get_type_arch (elttype);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
int width = TYPE_LENGTH (elttype);
|
||||
|
@ -2812,7 +2808,6 @@ val_print_string (struct type *elttype, const char *encoding,
|
|||
|
||||
err = read_string (addr, len, width, fetchlimit, byte_order,
|
||||
&buffer, &bytes_read);
|
||||
old_chain = make_cleanup (xfree, buffer);
|
||||
|
||||
addr += bytes_read;
|
||||
|
||||
|
@ -2823,8 +2818,8 @@ val_print_string (struct type *elttype, const char *encoding,
|
|||
/* Determine found_nul by looking at the last character read. */
|
||||
found_nul = 0;
|
||||
if (bytes_read >= width)
|
||||
found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
|
||||
byte_order) == 0;
|
||||
found_nul = extract_unsigned_integer (buffer.get () + bytes_read - width,
|
||||
width, byte_order) == 0;
|
||||
if (len == -1 && !found_nul)
|
||||
{
|
||||
gdb_byte *peekbuf;
|
||||
|
@ -2852,7 +2847,7 @@ val_print_string (struct type *elttype, const char *encoding,
|
|||
and then the error message. */
|
||||
if (err == 0 || bytes_read > 0)
|
||||
{
|
||||
LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width,
|
||||
LA_PRINT_STRING (stream, elttype, buffer.get (), bytes_read / width,
|
||||
encoding, force_ellipsis, options);
|
||||
}
|
||||
|
||||
|
@ -2866,7 +2861,6 @@ val_print_string (struct type *elttype, const char *encoding,
|
|||
}
|
||||
|
||||
gdb_flush (stream);
|
||||
do_cleanups (old_chain);
|
||||
|
||||
return (bytes_read / width);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue