public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: Yao Qi <yao@codesourcery.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH 03/11] Iterate over 'struct varobj_item' instead of PyObject
Date: Tue, 21 Jan 2014 20:44:00 -0000	[thread overview]
Message-ID: <52DEDC27.9010503@redhat.com> (raw)
In-Reply-To: <1385258996-26047-4-git-send-email-yao@codesourcery.com>

On 11/23/2013 06:09 PM, Yao Qi wrote:
> gdb:
>
> 2013-11-24  Pedro Alves  <pedro@codesourcery.com>
> 	    Yao Qi  <yao@codesourcery.com>
>
> 	* python/py-varobj.c (py_varobj_iter_next): Move some code
> 	from varobj.c.
> 	(py_varobj_get_iterator):
          ^^^^^^^^^^^^^^^^^^^^^^
Superfluous? I don't see any changes to that function.

> 	* varobj-iter.h (struct varobj_item): New.  Moved from
> 	varobj.c.

I would remove "New." That threw me a little while reading the patch. It 
looked familiar! Simply saying that you moved it is sufficient.

> 	* varobj.c: Move "varobj-iter.h" inclusion earlier.
> 	(struct varobj_item): Remove.

I think it is more concise to say "Moved to varobj-iter.h" instead of 
"Remove".

> 	(varobj_clear_saved_item): New function.
> 	(update_dynamic_varobj_children): Move python-related code to
> 	py-varobj.c.
> 	(free_variable): Call varobj_clear_saved_item.
> ---
>   gdb/python/py-varobj.c |   17 ++++++++++-
>   gdb/varobj-iter.h      |   12 ++++++-
>   gdb/varobj.c           |   73 ++++++++++++++++-------------------------------
>   3 files changed, 51 insertions(+), 51 deletions(-)
>
> diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
> index 6588fc2..506e865 100644
> --- a/gdb/python/py-varobj.c
> +++ b/gdb/python/py-varobj.c
> @@ -51,6 +51,9 @@ py_varobj_iter_next (struct varobj_iter *self)
>     struct py_varobj_iter *t = (struct py_varobj_iter *) self;
>     struct cleanup *back_to;
>     PyObject *item;
> +  PyObject *py_v;
> +  varobj_item *vitem;
> +  const char *name = NULL;
>
>     back_to = varobj_ensure_python_env (self->var);
>
> @@ -98,9 +101,21 @@ py_varobj_iter_next (struct varobj_iter *self)
>   	}
>       }
>
> +  if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
> +    {
> +      gdbpy_print_stack ();
> +      error (_("Invalid item from the child list"));
> +    }
> +
> +  vitem = xmalloc (sizeof *vitem);

You can use "XNEW (struct varobj_item)" here, too, although there isn't 
any real overriding reason to do so (other than personal preference). 
Feel free to ignore me, though. There is no hard rule for this in 
gdb-land as far as I know.

> +  vitem->value = convert_value_from_python (py_v);
> +  if (vitem->value == NULL)
> +    gdbpy_print_stack ();
> +  vitem->name = xstrdup (name);
> +
>     self->next_raw_index++;
>     do_cleanups (back_to);
> -  return item;
> +  return vitem;
>   }
>
>   /* The 'vtable' of pretty-printed python varobj iterators.  */
> diff --git a/gdb/varobj-iter.h b/gdb/varobj-iter.h
> index 59be278..b4bda82 100644
> --- a/gdb/varobj-iter.h
> +++ b/gdb/varobj-iter.h
> @@ -14,9 +14,17 @@
>      You should have received a copy of the GNU General Public License
>      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>
> -struct varobj_iter_ops;
> +/* A node or item of varobj, composed by the name and the value.  */
> +
> +typedef struct varobj_item
> +{
> +  /* Name of this item.  */
> +  char *name;
> +  /* Value of this item.  */
> +  struct value *value;
> +} varobj_item;
>

[Changes mentioned in last patch for above hunk]

> -typedef PyObject varobj_item;
> +struct varobj_iter_ops;
>
>   /* A dynamic varobj iterator "class".  */
>
> diff --git a/gdb/varobj.c b/gdb/varobj.c
> index 7a8305b..28e934c 100644
> --- a/gdb/varobj.c
> +++ b/gdb/varobj.c
> @@ -33,6 +33,7 @@
>   #include "vec.h"
>   #include "gdbthread.h"
>   #include "inferior.h"
> +#include "varobj-iter.h"
>
>   #if HAVE_PYTHON
>   #include "python/python.h"
> @@ -41,8 +42,6 @@
>   typedef int PyObject;
>   #endif
>
> -#include "varobj-iter.h"
> -
>   /* Non-zero if we want to see trace of varobj level stuff.  */
>
>   unsigned int varobjdebug = 0;
> @@ -110,16 +109,6 @@ struct varobj_root
>     struct varobj_root *next;
>   };
>
> -/* A node or item of varobj, composed by the name and the value.  */
> -
> -struct varobj_item
> -{
> -  /* Name of this item.  */
> -  char *name;
> -  /* Value of this item.  */
> -  struct value *value;
> -};
> -
>   /* Dynamic part of varobj.  */
>
>   struct varobj_dynamic
> @@ -787,6 +776,18 @@ varobj_get_iterator (struct varobj *var)
>   requested an interator from a non-dynamic varobj"));
>   }
>
> +/* Release and clear VAR's saved item, if any.  */
> +
> +static void
> +varobj_clear_saved_item (struct varobj_dynamic *var)
> +{
> +  if (var->saved_item != NULL)
> +    {
> +      value_free (var->saved_item->value);
> +      xfree (var->saved_item);
> +      var->saved_item = NULL;
> +    }
> +}
>   #endif
>
>   static int
> @@ -801,14 +802,8 @@ update_dynamic_varobj_children (struct varobj *var,
>   				int to)
>   {
>   #if HAVE_PYTHON
> -  struct cleanup *back_to;
>     int i;
>
> -  if (!gdb_python_initialized)
> -    return 0;
> -
> -  back_to = varobj_ensure_python_env (var);
> -
>     *cchanged = 0;
>
>     if (update_children || var->dynamic->child_iter == NULL)
> @@ -816,16 +811,12 @@ update_dynamic_varobj_children (struct varobj *var,
>         varobj_iter_delete (var->dynamic->child_iter);
>         var->dynamic->child_iter = varobj_get_iterator (var);
>
> -      Py_XDECREF (var->dynamic->saved_item);
> -      var->dynamic->saved_item = NULL;
> +      varobj_clear_saved_item (var->dynamic);
>
>         i = 0;
>
>         if (var->dynamic->child_iter == NULL)
> -	{
> -	  do_cleanups (back_to);
> -	  return 0;
> -	}
> +	return 0;
>       }
>     else
>       i = VEC_length (varobj_p, var->children);
> @@ -834,10 +825,10 @@ update_dynamic_varobj_children (struct varobj *var,
>        are more children.  */
>     for (; to < 0 || i < to + 1; ++i)
>       {
> -      PyObject *item;
> +      varobj_item *item;
>
>         /* See if there was a leftover from last time.  */
> -      if (var->dynamic->saved_item)
> +      if (var->dynamic->saved_item != NULL)
>   	{
>   	  item = var->dynamic->saved_item;
>   	  var->dynamic->saved_item = NULL;
> @@ -845,6 +836,10 @@ update_dynamic_varobj_children (struct varobj *var,
>         else
>   	{
>   	  item = varobj_iter_next (var->dynamic->child_iter);
> +	  /* Release vitem->value so its lifetime is not bound to the
> +	     execution of a command.  */
> +	  if (item != NULL && item->value != NULL)
> +	    release_value_or_incref (item->value);
>   	}
>
>         if (item == NULL)
> @@ -857,36 +852,19 @@ update_dynamic_varobj_children (struct varobj *var,
>         /* We don't want to push the extra child on any report list.  */
>         if (to < 0 || i < to)
>   	{
> -	  PyObject *py_v;
> -	  const char *name;
> -	  struct varobj_item varobj_item;
> -	  struct cleanup *inner;
>   	  int can_mention = from < 0 || i >= from;
>
> -	  inner = make_cleanup_py_decref (item);
> -
> -	  if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
> -	    {
> -	      gdbpy_print_stack ();
> -	      error (_("Invalid item from the child list"));
> -	    }
> -
> -	  varobj_item.value = convert_value_from_python (py_v);
> -	  if (varobj_item.value == NULL)
> -	    gdbpy_print_stack ();
> -	  varobj_item.name = xstrdup (name);
> -
>   	  install_dynamic_child (var, can_mention ? changed : NULL,
>   				 can_mention ? type_changed : NULL,
>   				 can_mention ? new : NULL,
>   				 can_mention ? unchanged : NULL,
>   				 can_mention ? cchanged : NULL, i,
> -				 &varobj_item);
> -	  do_cleanups (inner);
> +				 item);
> +
> +	  xfree (item);
>   	}
>         else
>   	{
> -	  Py_XDECREF (var->dynamic->saved_item);
>   	  var->dynamic->saved_item = item;
>
>   	  /* We want to truncate the child list just before this
> @@ -2180,12 +2158,11 @@ free_variable (struct varobj *var)
>
>         Py_XDECREF (var->dynamic->constructor);
>         Py_XDECREF (var->dynamic->pretty_printer);
> -      Py_XDECREF (var->dynamic->child_iter);

If I'm reading this right, this statement was moved to the python 
iterator dtor function. What happens if we do not iterate over all 
children and then delete the varobj? I don't see where 
varobj_delete_iter is called in that case, i.e., isn't this leaked in 
this scenario?

> -      Py_XDECREF (var->dynamic->saved_item);
>         do_cleanups (cleanup);
>       }
>   #endif
>
> +  varobj_clear_saved_item (var->dynamic);
>     value_free (var->value);
>
>     /* Free the expression if this is a root variable.  */
>

  reply	other threads:[~2014-01-21 20:44 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-24  5:04 [RCF 00/11] Visit varobj available children only in MI Yao Qi
2013-11-24  2:12 ` [PATCH 05/11] Rename varobj_pretty_printed_p to varobj_is_dynamic_p Yao Qi
2014-01-21 20:44   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 11/11] Test case Yao Qi
2014-01-21 20:49   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 06/11] Use varobj_is_dynamic_p more widely Yao Qi
2014-01-21 20:44   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 02/11] Generalize varobj iterator Yao Qi
2014-01-21 20:44   ` Keith Seitz
2014-01-22  1:07     ` Doug Evans
2013-11-24  2:12 ` [PATCH 01/11] Use 'struct varobj_item' to represent name and value pair Yao Qi
2014-01-21 20:43   ` Keith Seitz
2014-01-22  1:00     ` Doug Evans
2014-01-23  4:08       ` Yao Qi
2014-01-23 16:08         ` Doug Evans
2013-11-24  2:12 ` [PATCH 08/11] Iterator varobj_items by their availability Yao Qi
2014-01-21 20:46   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 07/11] MI option --available-children-only Yao Qi
2014-01-21 20:45   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 10/11] Match dynamic="1" in the output of -var-list-children Yao Qi
2014-01-21 20:47   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 03/11] Iterate over 'struct varobj_item' instead of PyObject Yao Qi
2014-01-21 20:44   ` Keith Seitz [this message]
2013-11-24  2:12 ` [PATCH 04/11] Remove #if HAVE_PYTHON Yao Qi
2014-01-21 20:44   ` Keith Seitz
2013-11-24  2:12 ` [PATCH 09/11] Delete varobj's children on traceframe is changed Yao Qi
2014-01-21 20:47   ` Keith Seitz
2013-12-02  9:09 ` [RCF 00/11] Visit varobj available children only in MI Yao Qi
2013-12-17 12:54 ` Yao Qi
2014-01-07 18:22 ` Keith Seitz
2014-01-08 11:41   ` Joel Brobecker
2014-01-08 14:27   ` Yao Qi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52DEDC27.9010503@redhat.com \
    --to=keiths@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=yao@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).