From 09ca9e2e34b93e8e12d6a0a4bad469b2b4c2f415 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 15 Oct 2010 18:54:13 +0000 Subject: [PATCH] PR python/11948: * varobj.c (value_get_print_value): Use val_print_string to print lazy strings. * python/py-prettyprint.c (print_string_repr): Use val_print_string to print lazy strings. Fix cleanup logic. (print_children): Likewise. * python/python-internal.h (gdbpy_extract_lazy_string): Update. * python/py-lazy-string.c (gdbpy_extract_lazy_string): Rewrite. Change return type to 'void', add 'addr' argument. * value.h (val_print_string): Update. * valprint.c (val_print_string): Add 'encoding' argument. * printcmd.c (print_formatted): Update. * p-valprint.c (pascal_val_print): Update. * m2-valprint.c (print_unpacked_pointer): Update. (m2_print_array_contents): Likewise. * jv-valprint.c (java_value_print): Update. * f-valprint.c (f_val_print): Update. * c-valprint.c (c_val_print): Update. * auxv.c (fprint_target_auxv): Update. --- gdb/ChangeLog | 22 ++++++++ gdb/auxv.c | 2 +- gdb/c-valprint.c | 2 +- gdb/f-valprint.c | 4 +- gdb/jv-valprint.c | 3 +- gdb/m2-valprint.c | 4 +- gdb/p-valprint.c | 6 +- gdb/printcmd.c | 2 +- gdb/python/py-lazy-string.c | 93 ++++++------------------------- gdb/python/py-prettyprint.c | 105 +++++++++++++++++------------------ gdb/python/python-internal.h | 6 +- gdb/valprint.c | 7 ++- gdb/value.h | 3 +- gdb/varobj.c | 41 +++++++------- 14 files changed, 135 insertions(+), 165 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a7029cfd68..203dc3c2c6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2010-10-15 Tom Tromey + + PR python/11948: + * varobj.c (value_get_print_value): Use val_print_string to print + lazy strings. + * python/py-prettyprint.c (print_string_repr): Use + val_print_string to print lazy strings. Fix cleanup logic. + (print_children): Likewise. + * python/python-internal.h (gdbpy_extract_lazy_string): Update. + * python/py-lazy-string.c (gdbpy_extract_lazy_string): Rewrite. + Change return type to 'void', add 'addr' argument. + * value.h (val_print_string): Update. + * valprint.c (val_print_string): Add 'encoding' argument. + * printcmd.c (print_formatted): Update. + * p-valprint.c (pascal_val_print): Update. + * m2-valprint.c (print_unpacked_pointer): Update. + (m2_print_array_contents): Likewise. + * jv-valprint.c (java_value_print): Update. + * f-valprint.c (f_val_print): Update. + * c-valprint.c (c_val_print): Update. + * auxv.c (fprint_target_auxv): Update. + 2010-10-15 Doug Evans Jan Kratochvil diff --git a/gdb/auxv.c b/gdb/auxv.c index 593b0c8059..71144dc6b6 100644 --- a/gdb/auxv.c +++ b/gdb/auxv.c @@ -401,7 +401,7 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops) if (opts.addressprint) fprintf_filtered (file, "%s", paddress (target_gdbarch, val)); val_print_string (builtin_type (target_gdbarch)->builtin_char, - val, -1, file, &opts); + NULL, val, -1, file, &opts); fprintf_filtered (file, "\n"); } break; diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 521460b21f..bc524bd86c 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -289,7 +289,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (c_textual_element_type (unresolved_elttype, options->format) && addr != 0) { - i = val_print_string (unresolved_elttype, addr, -1, stream, + i = val_print_string (unresolved_elttype, NULL, addr, -1, stream, options); } else if (cp_is_vtbl_member (type)) diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 85f698d5da..e27f79edf7 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -299,8 +299,8 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, && TYPE_CODE (elttype) == TYPE_CODE_INT && (options->format == 0 || options->format == 's') && addr != 0) - i = val_print_string (TYPE_TARGET_TYPE (type), addr, -1, stream, - options); + i = val_print_string (TYPE_TARGET_TYPE (type), NULL, addr, -1, + stream, options); /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c index 1819b50323..0a2cc538aa 100644 --- a/gdb/jv-valprint.c +++ b/gdb/jv-valprint.c @@ -239,7 +239,8 @@ java_value_print (struct value *val, struct ui_file *stream, value_free_to_mark (mark); /* Release unnecessary values */ char_type = builtin_java_type (gdbarch)->builtin_char; - val_print_string (char_type, data + boffset, count, stream, options); + val_print_string (char_type, NULL, data + boffset, count, stream, + options); return 0; } diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c index e27ce8c1a2..f826ca4d42 100644 --- a/gdb/m2-valprint.c +++ b/gdb/m2-valprint.c @@ -235,7 +235,7 @@ print_unpacked_pointer (struct type *type, && TYPE_CODE (elttype) == TYPE_CODE_INT && (options->format == 0 || options->format == 's') && addr != 0) - return val_print_string (TYPE_TARGET_TYPE (type), addr, -1, + return val_print_string (TYPE_TARGET_TYPE (type), NULL, addr, -1, stream, options); return 0; @@ -296,7 +296,7 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr, || ((current_language->la_language == language_m2) && (TYPE_CODE (type) == TYPE_CODE_CHAR))) && (options->format == 0 || options->format == 's')) - val_print_string (type, address, len+1, stream, options); + val_print_string (type, NULL, address, len+1, stream, options); else { fprintf_filtered (stream, "{"); diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index 4d39bed265..44a2d72e5d 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -183,7 +183,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, && addr != 0) { /* no wide string yet */ - i = val_print_string (elttype, addr, -1, stream, options); + i = val_print_string (elttype, NULL, addr, -1, stream, options); } /* also for pointers to pascal strings */ /* Note: this is Free Pascal specific: @@ -202,7 +202,9 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, string_length = extract_unsigned_integer (buffer, length_size, byte_order); xfree (buffer); - i = val_print_string (char_type ,addr + string_pos, string_length, stream, options); + i = val_print_string (char_type, NULL, + addr + string_pos, string_length, + stream, options); } else if (pascal_object_is_vtbl_member (type)) { diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 5ffa099d87..5586767ba0 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -298,7 +298,7 @@ print_formatted (struct value *val, int size, struct type *elttype = value_type (val); next_address = (value_address (val) - + val_print_string (elttype, + + val_print_string (elttype, NULL, value_address (val), -1, stream, options) * len); } diff --git a/gdb/python/py-lazy-string.c b/gdb/python/py-lazy-string.c index 23cf13a057..a7ef69f8c5 100644 --- a/gdb/python/py-lazy-string.c +++ b/gdb/python/py-lazy-string.c @@ -24,6 +24,7 @@ #include "exceptions.h" #include "valprint.h" #include "language.h" +#include "gdb_assert.h" typedef struct { PyObject_HEAD @@ -169,86 +170,26 @@ gdbpy_is_lazy_string (PyObject *result) return PyObject_TypeCheck (result, &lazy_string_object_type); } -/* Extract and return the actual string from the lazy string object - STRING. Addtionally, the string type is written to *STR_TYPE, the - string length is written to *LENGTH, and the string encoding is - written to *ENCODING. On error, NULL is returned. The caller is - responsible for freeing the returned buffer. */ -gdb_byte * -gdbpy_extract_lazy_string (PyObject *string, struct type **str_type, - long *length, char **encoding) -{ - int width; - int bytes_read; - gdb_byte *buffer = NULL; - int errcode = 0; - CORE_ADDR addr; - struct gdbarch *gdbarch; - enum bfd_endian byte_order; - PyObject *py_len = NULL, *py_encoding = NULL; - PyObject *py_addr = NULL, *py_type = NULL; - volatile struct gdb_exception except; - - py_len = PyObject_GetAttrString (string, "length"); - py_encoding = PyObject_GetAttrString (string, "encoding"); - py_addr = PyObject_GetAttrString (string, "address"); - py_type = PyObject_GetAttrString (string, "type"); - - /* A NULL encoding, length, address or type is not ok. */ - if (!py_len || !py_encoding || !py_addr || !py_type) - goto error; - - *length = PyLong_AsLong (py_len); - addr = PyLong_AsUnsignedLongLong (py_addr); - - /* If the user supplies Py_None an encoding, set encoding to NULL. - This will trigger the resulting LA_PRINT_CALL to automatically - select an encoding. */ - if (py_encoding == Py_None) - *encoding = NULL; - else - *encoding = xstrdup (PyString_AsString (py_encoding)); +/* Extract the parameters from the lazy string object STRING. + ENCODING will either be set to NULL, or will be allocated with + xmalloc, in which case the callers is responsible for freeing + it. */ - *str_type = type_object_to_type (py_type); - gdbarch = get_type_arch (*str_type); - byte_order = gdbarch_byte_order (gdbarch); - width = TYPE_LENGTH (*str_type); +void +gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr, + struct type **str_type, + long *length, char **encoding) +{ + lazy_string_object *lazy; - TRY_CATCH (except, RETURN_MASK_ALL) - { - errcode = read_string (addr, *length, width, - *length, byte_order, &buffer, - &bytes_read); - } - if (except.reason < 0) - { - PyErr_Format (except.reason == RETURN_QUIT \ - ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ - "%s", except.message); \ - goto error; + gdb_assert (gdbpy_is_lazy_string (string)); - } + lazy = (lazy_string_object *) string; - if (errcode) - goto error; - - *length = bytes_read / width; - - Py_DECREF (py_encoding); - Py_DECREF (py_len); - Py_DECREF (py_addr); - Py_DECREF (py_type); - return buffer; - - error: - Py_XDECREF (py_encoding); - Py_XDECREF (py_len); - Py_XDECREF (py_addr); - Py_XDECREF (py_type); - xfree (buffer); - *length = 0; - *str_type = NULL; - return NULL; + *addr = lazy->address; + *str_type = lazy->type; + *length = lazy->length; + *encoding = lazy->encoding ? xstrdup (lazy->encoding) : NULL; } diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index cc6a346716..37c407843d 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -275,53 +275,51 @@ print_string_repr (PyObject *printer, const char *hint, py_str = pretty_print_one_value (printer, &replacement); if (py_str) { + struct cleanup *cleanup = make_cleanup_py_decref (py_str); + if (py_str == Py_None) is_py_none = 1; - else + else if (gdbpy_is_lazy_string (py_str)) { - gdb_byte *output = NULL; + CORE_ADDR addr; long length; struct type *type; char *encoding = NULL; - PyObject *string = NULL; - int is_lazy; - is_lazy = gdbpy_is_lazy_string (py_str); - if (is_lazy) - output = gdbpy_extract_lazy_string (py_str, &type, &length, &encoding); - else - { - string = python_string_to_target_python_string (py_str); - if (string) - { - output = PyString_AsString (string); - length = PyString_Size (string); - type = builtin_type (gdbarch)->builtin_char; - } - else - gdbpy_print_stack (); - - } - - if (output) + make_cleanup (free_current_contents, &encoding); + gdbpy_extract_lazy_string (py_str, &addr, &type, + &length, &encoding); + + val_print_string (type, encoding, addr, (int) length, + stream, options); + } + else + { + PyObject *string; + + string = python_string_to_target_python_string (py_str); + if (string) { - if (is_lazy || (hint && !strcmp (hint, "string"))) - LA_PRINT_STRING (stream, type, output, length, encoding, + gdb_byte *output; + long length; + struct type *type; + + make_cleanup_py_decref (string); + output = PyString_AsString (string); + length = PyString_Size (string); + type = builtin_type (gdbarch)->builtin_char; + + if (hint && !strcmp (hint, "string")) + LA_PRINT_STRING (stream, type, output, length, NULL, 0, options); else fputs_filtered (output, stream); } else gdbpy_print_stack (); - - if (string) - Py_DECREF (string); - else - xfree (output); - - xfree (encoding); - Py_DECREF (py_str); } + + do_cleanups (cleanup); } else if (replacement) { @@ -548,32 +546,31 @@ print_children (PyObject *printer, const char *hint, fputs_filtered (" = ", stream); } - if (gdbpy_is_lazy_string (py_v) || gdbpy_is_string (py_v)) + if (gdbpy_is_lazy_string (py_v)) { - gdb_byte *output = NULL; + CORE_ADDR addr; + struct type *type; + long length; + char *encoding = NULL; - if (gdbpy_is_lazy_string (py_v)) - { - struct type *type; - long length; - char *encoding = NULL; - - output = gdbpy_extract_lazy_string (py_v, &type, - &length, &encoding); - if (!output) - gdbpy_print_stack (); - LA_PRINT_STRING (stream, type, output, length, encoding, - 0, options); - xfree (encoding); - xfree (output); - } + make_cleanup (free_current_contents, &encoding); + gdbpy_extract_lazy_string (py_v, &addr, &type, &length, &encoding); + + val_print_string (type, encoding, addr, (int) length, stream, + options); + + do_cleanups (inner_cleanup); + } + else if (gdbpy_is_string (py_v)) + { + gdb_byte *output; + + output = python_string_to_host_string (py_v); + if (!output) + gdbpy_print_stack (); else { - output = python_string_to_host_string (py_v); - if (!output) - gdbpy_print_stack (); - else - fputs_filtered (output, stream); + fputs_filtered (output, stream); xfree (output); } } diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index c5d1e7335d..d00c23e313 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -209,9 +209,9 @@ char *gdbpy_obj_to_string (PyObject *obj); char *gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue); int gdbpy_is_lazy_string (PyObject *result); -gdb_byte *gdbpy_extract_lazy_string (PyObject *string, - struct type **str_type, - long *length, char **encoding); +void gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr, + struct type **str_type, + long *length, char **encoding); int gdbpy_is_value_object (PyObject *obj); diff --git a/gdb/valprint.c b/gdb/valprint.c index ad6268e2c4..4b3789ed14 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1414,10 +1414,13 @@ read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit, characters, of WIDTH bytes a piece, to STREAM. If LEN is -1, printing stops at the first null byte, otherwise printing proceeds (including null bytes) until either print_max or LEN characters have been printed, - whichever is smaller. */ + whichever is smaller. ENCODING is the name of the string's + encoding. It can be NULL, in which case the target encoding is + assumed. */ int -val_print_string (struct type *elttype, CORE_ADDR addr, int len, +val_print_string (struct type *elttype, const char *encoding, + CORE_ADDR addr, int len, struct ui_file *stream, const struct value_print_options *options) { diff --git a/gdb/value.h b/gdb/value.h index 12cbc0a702..d7912a89bb 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -687,7 +687,8 @@ extern int common_val_print (struct value *val, const struct value_print_options *options, const struct language_defn *language); -extern int val_print_string (struct type *elttype, CORE_ADDR addr, int len, +extern int val_print_string (struct type *elttype, const char *encoding, + CORE_ADDR addr, int len, struct ui_file *stream, const struct value_print_options *options); diff --git a/gdb/varobj.c b/gdb/varobj.c index e56bbf71de..2eacfa2317 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -2479,13 +2479,15 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, struct varobj *var) { struct ui_file *stb; - struct cleanup *old_chain; + struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); gdb_byte *thevalue = NULL; struct value_print_options opts; struct type *type = NULL; long len = 0; char *encoding = NULL; struct gdbarch *gdbarch = NULL; + CORE_ADDR str_addr; + int string_print = 0; if (value == NULL) return NULL; @@ -2493,9 +2495,10 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, gdbarch = get_type_arch (value_type (value)); #if HAVE_PYTHON { - struct cleanup *back_to = varobj_ensure_python_env (var); PyObject *value_formatter = var->pretty_printer; + varobj_ensure_python_env (var); + if (value_formatter) { /* First check to see if we have any children at all. If so, @@ -2507,7 +2510,6 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, { char *hint; struct value *replacement; - int string_print = 0; PyObject *output = NULL; hint = gdbpy_get_display_hint (value_formatter); @@ -2522,10 +2524,13 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, &replacement); if (output) { + make_cleanup_py_decref (output); + if (gdbpy_is_lazy_string (output)) { - thevalue = gdbpy_extract_lazy_string (output, &type, - &len, &encoding); + gdbpy_extract_lazy_string (output, &str_addr, &type, + &len, &encoding); + make_cleanup (free_current_contents, &encoding); string_print = 1; } else @@ -2541,38 +2546,36 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, thevalue = xmemdup (s, len + 1, len + 1); type = builtin_type (gdbarch)->builtin_char; Py_DECREF (py_str); + + if (!string_print) + { + do_cleanups (old_chain); + return thevalue; + } + + make_cleanup (xfree, thevalue); } else gdbpy_print_stack (); } - Py_DECREF (output); - } - if (thevalue && !string_print) - { - do_cleanups (back_to); - xfree (encoding); - return thevalue; } if (replacement) value = replacement; } } - do_cleanups (back_to); } #endif stb = mem_fileopen (); - old_chain = make_cleanup_ui_file_delete (stb); + make_cleanup_ui_file_delete (stb); get_formatted_print_options (&opts, format_code[(int) format]); opts.deref_ref = 0; opts.raw = 1; if (thevalue) - { - make_cleanup (xfree, thevalue); - make_cleanup (xfree, encoding); - LA_PRINT_STRING (stb, type, thevalue, len, encoding, 0, &opts); - } + LA_PRINT_STRING (stb, type, thevalue, len, encoding, 0, &opts); + else if (string_print) + val_print_string (type, encoding, str_addr, len, stb, &opts); else common_val_print (value, stb, 0, &opts, current_language); thevalue = ui_file_xstrdup (stb, NULL); -- 2.34.1