PR python/11948:
authorTom Tromey <tromey@redhat.com>
Fri, 15 Oct 2010 18:54:13 +0000 (18:54 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 15 Oct 2010 18:54:13 +0000 (18:54 +0000)
* 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.

14 files changed:
gdb/ChangeLog
gdb/auxv.c
gdb/c-valprint.c
gdb/f-valprint.c
gdb/jv-valprint.c
gdb/m2-valprint.c
gdb/p-valprint.c
gdb/printcmd.c
gdb/python/py-lazy-string.c
gdb/python/py-prettyprint.c
gdb/python/python-internal.h
gdb/valprint.c
gdb/value.h
gdb/varobj.c

index a7029cf..203dc3c 100644 (file)
@@ -1,3 +1,25 @@
+2010-10-15  Tom Tromey  <tromey@redhat.com>
+
+       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  <dje@google.com>
            Jan Kratochvil  <jan.kratochvil@redhat.com>
 
index 593b0c8..71144dc 100644 (file)
@@ -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;
index 521460b..bc524bd 100644 (file)
@@ -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))
index 85f698d..e27f79e 100644 (file)
@@ -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
index 1819b50..0a2cc53 100644 (file)
@@ -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;
     }
index e27ce8c..f826ca4 100644 (file)
@@ -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, "{");
index 4d39bed..44a2d72 100644 (file)
@@ -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))
        {
index 5ffa099..5586767 100644 (file)
@@ -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);
          }
index 23cf13a..a7ef69f 100644 (file)
@@ -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;
 }
 
 \f
index cc6a346..37c4078 100644 (file)
@@ -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);
            }
        }
index c5d1e73..d00c23e 100644 (file)
@@ -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);
 
index ad6268e..4b3789e 100644 (file)
@@ -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)
 {
index 12cbc0a..d7912a8 100644 (file)
@@ -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);
 
index e56bbf7..2eacfa2 100644 (file)
@@ -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);