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
|
@ -1,3 +1,16 @@
|
||||||
|
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".
|
||||||
|
|
||||||
2018-06-18 Tom Tromey <tom@tromey.com>
|
2018-06-18 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* ser-mingw.c (struct pipe_state_destroyer): New.
|
* ser-mingw.c (struct pipe_state_destroyer): New.
|
||||||
|
|
13
gdb/c-lang.c
13
gdb/c-lang.c
|
@ -234,7 +234,7 @@ c_printstr (struct ui_file *stream, struct type *type,
|
||||||
target charset. */
|
target charset. */
|
||||||
|
|
||||||
void
|
void
|
||||||
c_get_string (struct value *value, gdb_byte **buffer,
|
c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
int *length, struct type **char_type,
|
int *length, struct type **char_type,
|
||||||
const char **charset)
|
const char **charset)
|
||||||
{
|
{
|
||||||
|
@ -300,8 +300,8 @@ c_get_string (struct value *value, gdb_byte **buffer,
|
||||||
/* I is now either a user-defined length, the number of non-null
|
/* I is now either a user-defined length, the number of non-null
|
||||||
characters, or FETCHLIMIT. */
|
characters, or FETCHLIMIT. */
|
||||||
*length = i * width;
|
*length = i * width;
|
||||||
*buffer = (gdb_byte *) xmalloc (*length);
|
buffer->reset ((gdb_byte *) xmalloc (*length));
|
||||||
memcpy (*buffer, contents, *length);
|
memcpy (buffer->get (), contents, *length);
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -326,10 +326,7 @@ c_get_string (struct value *value, gdb_byte **buffer,
|
||||||
err = read_string (addr, *length, width, fetchlimit,
|
err = read_string (addr, *length, width, fetchlimit,
|
||||||
byte_order, buffer, length);
|
byte_order, buffer, length);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
{
|
memory_error (TARGET_XFER_E_IO, addr);
|
||||||
xfree (*buffer);
|
|
||||||
memory_error (TARGET_XFER_E_IO, addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the LENGTH is specified at -1, we want to return the string
|
/* If the LENGTH is specified at -1, we want to return the string
|
||||||
|
@ -339,7 +336,7 @@ c_get_string (struct value *value, gdb_byte **buffer,
|
||||||
if (req_length == -1)
|
if (req_length == -1)
|
||||||
/* If the last character is null, subtract it from LENGTH. */
|
/* If the last character is null, subtract it from LENGTH. */
|
||||||
if (*length > 0
|
if (*length > 0
|
||||||
&& extract_unsigned_integer (*buffer + *length - width,
|
&& extract_unsigned_integer (buffer->get () + *length - width,
|
||||||
width, byte_order) == 0)
|
width, byte_order) == 0)
|
||||||
*length -= width;
|
*length -= width;
|
||||||
|
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ gdbscm_value_to_string (SCM self, SCM rest)
|
||||||
char *encoding = NULL;
|
char *encoding = NULL;
|
||||||
SCM errors = SCM_BOOL_F;
|
SCM errors = SCM_BOOL_F;
|
||||||
int length = -1;
|
int length = -1;
|
||||||
gdb_byte *buffer = NULL;
|
gdb::unique_xmalloc_ptr<gdb_byte> buffer;
|
||||||
const char *la_encoding = NULL;
|
const char *la_encoding = NULL;
|
||||||
struct type *char_type = NULL;
|
struct type *char_type = NULL;
|
||||||
SCM result;
|
SCM result;
|
||||||
|
@ -1163,9 +1163,10 @@ gdbscm_value_to_string (SCM self, SCM rest)
|
||||||
scm_dynwind_begin ((scm_t_dynwind_flags) 0);
|
scm_dynwind_begin ((scm_t_dynwind_flags) 0);
|
||||||
|
|
||||||
gdbscm_dynwind_xfree (encoding);
|
gdbscm_dynwind_xfree (encoding);
|
||||||
gdbscm_dynwind_xfree (buffer);
|
gdb_byte *buffer_contents = buffer.release ();
|
||||||
|
gdbscm_dynwind_xfree (buffer_contents);
|
||||||
|
|
||||||
result = scm_from_stringn ((const char *) buffer,
|
result = scm_from_stringn ((const char *) buffer_contents,
|
||||||
length * TYPE_LENGTH (char_type),
|
length * TYPE_LENGTH (char_type),
|
||||||
(encoding != NULL && *encoding != '\0'
|
(encoding != NULL && *encoding != '\0'
|
||||||
? encoding
|
? encoding
|
||||||
|
|
|
@ -691,8 +691,9 @@ default_print_array_index (struct value *index_value, struct ui_file *stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
default_get_string (struct value *value, gdb_byte **buffer, int *length,
|
default_get_string (struct value *value,
|
||||||
struct type **char_type, const char **charset)
|
gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
|
int *length, struct type **char_type, const char **charset)
|
||||||
{
|
{
|
||||||
error (_("Getting a string is unsupported in this language."));
|
error (_("Getting a string is unsupported in this language."));
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,8 +366,10 @@ struct language_defn
|
||||||
characters, excluding any eventual terminating null character.
|
characters, excluding any eventual terminating null character.
|
||||||
Otherwise *LENGTH will include all characters - including any nulls.
|
Otherwise *LENGTH will include all characters - including any nulls.
|
||||||
CHARSET will hold the encoding used in the string. */
|
CHARSET will hold the encoding used in the string. */
|
||||||
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
|
void (*la_get_string) (struct value *value,
|
||||||
struct type **chartype, const char **charset);
|
gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
|
int *length, struct type **chartype,
|
||||||
|
const char **charset);
|
||||||
|
|
||||||
/* Return an expression that can be used for a location
|
/* Return an expression that can be used for a location
|
||||||
watchpoint. TYPE is a pointer type that points to the memory
|
watchpoint. TYPE is a pointer type that points to the memory
|
||||||
|
@ -627,8 +629,10 @@ int default_pass_by_reference (struct type *type);
|
||||||
void default_print_typedef (struct type *type, struct symbol *new_symbol,
|
void default_print_typedef (struct type *type, struct symbol *new_symbol,
|
||||||
struct ui_file *stream);
|
struct ui_file *stream);
|
||||||
|
|
||||||
void default_get_string (struct value *value, gdb_byte **buffer, int *length,
|
void default_get_string (struct value *value,
|
||||||
struct type **char_type, const char **charset);
|
gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
|
int *length, struct type **char_type,
|
||||||
|
const char **charset);
|
||||||
|
|
||||||
/* Default name hashing function. */
|
/* Default name hashing function. */
|
||||||
|
|
||||||
|
@ -638,8 +642,10 @@ void default_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||||
comparison operators hash to the same value. */
|
comparison operators hash to the same value. */
|
||||||
extern unsigned int default_search_name_hash (const char *search_name);
|
extern unsigned int default_search_name_hash (const char *search_name);
|
||||||
|
|
||||||
void c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
void c_get_string (struct value *value,
|
||||||
struct type **char_type, const char **charset);
|
gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
|
int *length, struct type **char_type,
|
||||||
|
const char **charset);
|
||||||
|
|
||||||
/* The default implementation of la_symbol_name_matcher. Matches with
|
/* The default implementation of la_symbol_name_matcher. Matches with
|
||||||
strncmp_iw. */
|
strncmp_iw. */
|
||||||
|
|
|
@ -517,9 +517,8 @@ static PyObject *
|
||||||
valpy_string (PyObject *self, PyObject *args, PyObject *kw)
|
valpy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
{
|
{
|
||||||
int length = -1;
|
int length = -1;
|
||||||
gdb_byte *buffer;
|
gdb::unique_xmalloc_ptr<gdb_byte> buffer;
|
||||||
struct value *value = ((value_object *) self)->value;
|
struct value *value = ((value_object *) self)->value;
|
||||||
PyObject *unicode;
|
|
||||||
const char *encoding = NULL;
|
const char *encoding = NULL;
|
||||||
const char *errors = NULL;
|
const char *errors = NULL;
|
||||||
const char *user_encoding = NULL;
|
const char *user_encoding = NULL;
|
||||||
|
@ -542,12 +541,9 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
END_CATCH
|
END_CATCH
|
||||||
|
|
||||||
encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
|
encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
|
||||||
unicode = PyUnicode_Decode ((const char *) buffer,
|
return PyUnicode_Decode ((const char *) buffer.get (),
|
||||||
length * TYPE_LENGTH (char_type),
|
length * TYPE_LENGTH (char_type),
|
||||||
encoding, errors);
|
encoding, errors);
|
||||||
xfree (buffer);
|
|
||||||
|
|
||||||
return unicode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A helper function that implements the various cast operators. */
|
/* A helper function that implements the various cast operators. */
|
||||||
|
|
|
@ -2096,10 +2096,10 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
|
||||||
return (nread);
|
return (nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a string from the inferior, at ADDR, with LEN characters of WIDTH bytes
|
/* Read a string from the inferior, at ADDR, with LEN characters of
|
||||||
each. Fetch at most FETCHLIMIT characters. BUFFER will be set to a newly
|
WIDTH bytes each. Fetch at most FETCHLIMIT characters. BUFFER
|
||||||
allocated buffer containing the string, which the caller is responsible to
|
will be set to a newly allocated buffer containing the string, and
|
||||||
free, and BYTES_READ will be set to the number of bytes read. Returns 0 on
|
BYTES_READ will be set to the number of bytes read. Returns 0 on
|
||||||
success, or a target_xfer_status on failure.
|
success, or a target_xfer_status on failure.
|
||||||
|
|
||||||
If LEN > 0, reads the lesser of LEN or FETCHLIMIT characters
|
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
|
int
|
||||||
read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
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. */
|
int errcode; /* Errno returned from bad reads. */
|
||||||
unsigned int nfetch; /* Chars to fetch / chars fetched. */
|
unsigned int nfetch; /* Chars to fetch / chars fetched. */
|
||||||
gdb_byte *bufptr; /* Pointer to next available byte in
|
gdb_byte *bufptr; /* Pointer to next available byte in
|
||||||
buffer. */
|
buffer. */
|
||||||
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
|
|
||||||
|
|
||||||
/* Loop until we either have all the characters, or we encounter
|
/* Loop until we either have all the characters, or we encounter
|
||||||
some error, such as bumping into the end of the address space. */
|
some error, such as bumping into the end of the address space. */
|
||||||
|
|
||||||
*buffer = NULL;
|
buffer->reset (nullptr);
|
||||||
|
|
||||||
old_chain = make_cleanup (free_current_contents, buffer);
|
|
||||||
|
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
|
@ -2143,8 +2141,8 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
|
||||||
one operation. */
|
one operation. */
|
||||||
unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);
|
unsigned int fetchlen = std::min ((unsigned) len, fetchlimit);
|
||||||
|
|
||||||
*buffer = (gdb_byte *) xmalloc (fetchlen * width);
|
buffer->reset ((gdb_byte *) xmalloc (fetchlen * width));
|
||||||
bufptr = *buffer;
|
bufptr = buffer->get ();
|
||||||
|
|
||||||
nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
|
nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode)
|
||||||
/ width;
|
/ 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);
|
nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize);
|
||||||
|
|
||||||
if (*buffer == NULL)
|
if (*buffer == NULL)
|
||||||
*buffer = (gdb_byte *) xmalloc (nfetch * width);
|
buffer->reset ((gdb_byte *) xmalloc (nfetch * width));
|
||||||
else
|
else
|
||||||
*buffer = (gdb_byte *) xrealloc (*buffer,
|
buffer->reset ((gdb_byte *) xrealloc (buffer->release (),
|
||||||
(nfetch + bufsize) * width);
|
(nfetch + bufsize) * width));
|
||||||
|
|
||||||
bufptr = *buffer + bufsize * width;
|
bufptr = buffer->get () + bufsize * width;
|
||||||
bufsize += nfetch;
|
bufsize += nfetch;
|
||||||
|
|
||||||
/* Read as much as we can. */
|
/* 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 */
|
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 */
|
&& !found_nul); /* haven't found NUL yet */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* Length of string is really 0! */
|
{ /* Length of string is really 0! */
|
||||||
/* We always allocate *buffer. */
|
/* We always allocate *buffer. */
|
||||||
*buffer = bufptr = (gdb_byte *) xmalloc (1);
|
buffer->reset ((gdb_byte *) xmalloc (1));
|
||||||
|
bufptr = buffer->get ();
|
||||||
errcode = 0;
|
errcode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bufptr and addr now point immediately beyond the last byte which we
|
/* bufptr and addr now point immediately beyond the last byte which we
|
||||||
consider part of the string (including a '\0' which ends the string). */
|
consider part of the string (including a '\0' which ends the string). */
|
||||||
*bytes_read = bufptr - *buffer;
|
*bytes_read = bufptr - buffer->get ();
|
||||||
|
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
discard_cleanups (old_chain);
|
|
||||||
|
|
||||||
return errcode;
|
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. */
|
int found_nul; /* Non-zero if we found the nul char. */
|
||||||
unsigned int fetchlimit; /* Maximum number of chars to print. */
|
unsigned int fetchlimit; /* Maximum number of chars to print. */
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */
|
gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
|
||||||
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
|
|
||||||
struct gdbarch *gdbarch = get_type_arch (elttype);
|
struct gdbarch *gdbarch = get_type_arch (elttype);
|
||||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
int width = TYPE_LENGTH (elttype);
|
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,
|
err = read_string (addr, len, width, fetchlimit, byte_order,
|
||||||
&buffer, &bytes_read);
|
&buffer, &bytes_read);
|
||||||
old_chain = make_cleanup (xfree, buffer);
|
|
||||||
|
|
||||||
addr += bytes_read;
|
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. */
|
/* Determine found_nul by looking at the last character read. */
|
||||||
found_nul = 0;
|
found_nul = 0;
|
||||||
if (bytes_read >= width)
|
if (bytes_read >= width)
|
||||||
found_nul = extract_unsigned_integer (buffer + bytes_read - width, width,
|
found_nul = extract_unsigned_integer (buffer.get () + bytes_read - width,
|
||||||
byte_order) == 0;
|
width, byte_order) == 0;
|
||||||
if (len == -1 && !found_nul)
|
if (len == -1 && !found_nul)
|
||||||
{
|
{
|
||||||
gdb_byte *peekbuf;
|
gdb_byte *peekbuf;
|
||||||
|
@ -2852,7 +2847,7 @@ val_print_string (struct type *elttype, const char *encoding,
|
||||||
and then the error message. */
|
and then the error message. */
|
||||||
if (err == 0 || bytes_read > 0)
|
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);
|
encoding, force_ellipsis, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2866,7 +2861,6 @@ val_print_string (struct type *elttype, const char *encoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_flush (stream);
|
gdb_flush (stream);
|
||||||
do_cleanups (old_chain);
|
|
||||||
|
|
||||||
return (bytes_read / width);
|
return (bytes_read / width);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,8 @@ extern void print_function_pointer_address (const struct value_print_options *op
|
||||||
|
|
||||||
extern int read_string (CORE_ADDR addr, int len, int width,
|
extern int read_string (CORE_ADDR addr, int len, int width,
|
||||||
unsigned int fetchlimit,
|
unsigned int fetchlimit,
|
||||||
enum bfd_endian byte_order, gdb_byte **buffer,
|
enum bfd_endian byte_order,
|
||||||
|
gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
|
||||||
int *bytes_read);
|
int *bytes_read);
|
||||||
|
|
||||||
extern void val_print_optimized_out (const struct value *val,
|
extern void val_print_optimized_out (const struct value *val,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue