Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] Python: PR/13327: expose laziness to Python
@ 2011-10-25 17:43 Paul Koning
  2011-10-25 18:24 ` Eli Zaretskii
  0 siblings, 1 reply; 3+ messages in thread
From: Paul Koning @ 2011-10-25 17:43 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

The attached implements a solution for PR/13327 by introducing the gdb.Value attribute "is_lazy" and method "fetch_lazy()".  It also reverts an earlier change I made that always immediately fetches values for gdb.Value, as discussed in http://sourceware.org/ml/gdb-patches/2011-10/msg00541.html .

The documentation briefly touches on how lazy fetching works in the discussion of the is_lazy attribute, but it doesn't more fully discuss it as a topic of its own.  I could try to do so, in the introductory material for gdb.Value.  Should I do that?

Ok to commit?

	paul

ChangeLog:

2011-10-25  Paul Koning  <paul_koning@dell.com>

	PR python/13327
	
	* python/py-value.c (value_to_value_object): Remove fetching of
	the value if it was lazy.
	(valpy_get_is_lazy): New function.
	(valpy_fetch_lazy): New function.

doc/Changelog:

2011-10-25  Paul Koning  <paul_koning@dell.com>

	PR python/13327
	
	* gdb.texinfo (Values From Inferior): Add is_lazy attribute,
	fetch_lazy method.

testsuite/ChangeLog:

2011-10-25  Paul Koning  <paul_koning@dell.com>

	PR python/13327
	
	* gdb.python/py-value.exp: Add testcases for is_lazy attribute,
	fetch_lazy method.

Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.880
diff -u -r1.880 gdb.texinfo
--- doc/gdb.texinfo	20 Oct 2011 12:31:29 -0000	1.880
+++ doc/gdb.texinfo	25 Oct 2011 17:24:18 -0000
@@ -21681,6 +21681,20 @@
 it will just return the static type of the value as in @kbd{ptype foo}
 (@pxref{Symbols, ptype}).
 @end defvar
+
+@defvar Value.is_lazy
+This read-only boolean attribute is true if the value has not yet
+been fetched from the inferior.  GDB does not fetch values until
+necessary, for efficiency.  For example:
+
+@smallexample
+myval = gdb.parse_and_eval ('somevar')
+@end smallexample
+
+The value of @var{somevar} is not fetched at this time.  It will be 
+fetched when the value is needed, or when the @code{fetch_lazy ()}
+method is invoked.  
+@end defvar
 @end table
 
 The following methods are provided:
@@ -21814,6 +21828,19 @@
 the @var{length} argument is not provided, the string will be fetched
 and encoded until a null of appropriate width is found.
 @end defun
+
+@defun Value.fetch_lazy ()
+If the @code{gdb.Value} object is currently a lazy value 
+(@code{gdb.Value.is_lazy} is @code{True}) then the value is
+fetched from the inferior.  Any errors that occur in the process
+will produce a Python exception.
+
+If the @code{gdb.Value} object is not a lazy value, this method
+has no effect.
+
+This method does not return a value.
+@end defun
+
 @end table
 
 @node Types In Python
Index: python/py-value.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-value.c,v
retrieving revision 1.28
diff -u -r1.28 py-value.c
--- python/py-value.c	7 Oct 2011 22:02:42 -0000	1.28
+++ python/py-value.c	25 Oct 2011 17:24:18 -0000
@@ -617,6 +617,43 @@
   Py_RETURN_FALSE;
 }
 
+/* Implements gdb.Value.is_lazy.  */
+static PyObject *
+valpy_get_is_lazy (PyObject *self, void *closure)
+{
+  struct value *value = ((value_object *) self)->value;
+  int opt = 0;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      opt = value_lazy (value);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (opt)
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Implements gdb.Value.fetch_lazy ().  */
+static PyObject *
+valpy_fetch_lazy (PyObject *self, PyObject *args)
+{
+  struct value *value = ((value_object *) self)->value;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (value_lazy (value))
+	value_fetch_lazy (value);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  Py_RETURN_NONE;
+}
+
 /* Calculate and return the address of the PyObject as the value of
    the builtin __hash__ call.  */
 static long 
@@ -1081,15 +1118,7 @@
 value_to_value_object (struct value *val)
 {
   value_object *val_obj;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
-    {
-      if (value_lazy (val))
-	value_fetch_lazy (val);
-    }
-  GDB_PY_HANDLE_EXCEPTION (except);
-  
   val_obj = PyObject_New (value_object, &value_object_type);
   if (val_obj != NULL)
     {
@@ -1276,6 +1305,10 @@
   { "type", valpy_get_type, NULL, "Type of the value.", NULL },
   { "dynamic_type", valpy_get_dynamic_type, NULL,
     "Dynamic type of the value.", NULL },
+  { "is_lazy", valpy_get_is_lazy, NULL,
+    "Boolean telling whether the value is lazy (not fetched yet\n\
+from the inferior).  A lazy value is fetched when needed, or when\n\
+the \"fetch_lazy()\" method is called.", NULL },
   {NULL}  /* Sentinel */
 };
 
@@ -1298,6 +1331,8 @@
   { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
     "string ([encoding] [, errors] [, length]) -> string\n\
 Return Unicode string representation of the value." },
+  { "fetch_lazy", valpy_fetch_lazy, METH_NOARGS, 
+    "Fetches the value from the inferior, if it was lazy." },
   {NULL}  /* Sentinel */
 };
 
Index: testsuite/gdb.python/py-value.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-value.exp,v
retrieving revision 1.24
diff -u -r1.24 py-value.exp
--- testsuite/gdb.python/py-value.exp	3 Oct 2011 16:15:26 -0000	1.24
+++ testsuite/gdb.python/py-value.exp	25 Oct 2011 17:24:19 -0000
@@ -236,17 +236,27 @@
     gdb_test "python print gdb.parse_and_eval('*(int*)0')" "gdb.MemoryError: Cannot access memory at address 0x0.*" $test
   }
 
-  # Test Python values are not lazy.
-  set test "memory error occurs even for possibly lazy values"
+  # Test Python lazy value handling
+  set test "memory error and lazy values"
   if {$can_read_0} {
     untested $test
   } else {
-    gdb_test "python inval = gdb.parse_and_eval('*(int*)0')" "gdb.MemoryError: Cannot access memory at address 0x0.*" $test
+    gdb_test "python inval = gdb.parse_and_eval('*(int*)0')"
+    gdb_test "python print inval.is_lazy" "True"
+    gdb_test "python inval2 = inval+1" "gdb.MemoryError: Cannot access memory at address 0x0.*" $test
+    gdb_test "python inval.fetch_lazy ()" "gdb.MemoryError: Cannot access memory at address 0x0.*" $test
   }
   gdb_test "python argc_lazy = gdb.parse_and_eval('argc')"
+  gdb_test "python argc_notlazy = gdb.parse_and_eval('argc')"
+  gdb_test "python argc_notlazy.fetch_lazy()"
+  gdb_test "python print argc_lazy.is_lazy" "True"
+  gdb_test "python print argc_notlazy.is_lazy" "False"
   gdb_test "print argc" " = 1" "sanity check argc"
+  gdb_test "python print argc_lazy.is_lazy" "\r\nTrue"
   gdb_test_no_output "set argc=2"
-  gdb_test "python print argc_lazy" "\r\n1"
+  gdb_test "python print argc_notlazy" "\r\n1"
+  gdb_test "python print argc_lazy" "\r\n2"
+  gdb_test "python print argc_lazy.is_lazy" "False"
 
   # Test string fetches,  both partial and whole.
   gdb_test "print st" "\"divide et impera\""


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFA] Python: PR/13327: expose laziness to Python
  2011-10-25 17:43 [RFA] Python: PR/13327: expose laziness to Python Paul Koning
@ 2011-10-25 18:24 ` Eli Zaretskii
  2011-10-25 18:54   ` Paul Koning
  0 siblings, 1 reply; 3+ messages in thread
From: Eli Zaretskii @ 2011-10-25 18:24 UTC (permalink / raw)
  To: Paul Koning; +Cc: gdb-patches, tromey

> From: Paul Koning <paulkoning@comcast.net>
> Date: Tue, 25 Oct 2011 13:38:20 -0400
> Cc: Tom Tromey <tromey@redhat.com>
> 
> The documentation briefly touches on how lazy fetching works in the discussion of the is_lazy attribute, but it doesn't more fully discuss it as a topic of its own.  I could try to do so, in the introductory material for gdb.Value.  Should I do that?

No, I think what you wrote is good enough.

> Ok to commit?

A few comments to the documentation part:

> +@defvar Value.is_lazy
> +This read-only boolean attribute is true if the value has not yet

"The attribute is true" sounds weird, doesn't it?  How about

 The value of this read-only attribute is @code{True} if @code{Value}
 has not yet been fetched ...

> +been fetched from the inferior.  GDB does not fetch values until
                                    ^^^
@value{GDBN}

> +necessary, for efficiency.  For example:
> +
> +@smallexample
> +myval = gdb.parse_and_eval ('somevar')
> +@end smallexample
> +
> +The value of @var{somevar} is not fetched at this time.  It will be 

@code{somevar}, not @var.  "somevar" does not stand for some symbol,
it's the symbol itself.

> +fetched when the value is needed, or when the @code{fetch_lazy ()}
> +method is invoked.  

@code{fetch_lazy}, please, without the parens.  "fetch_lazy()" looks
like a call to the method with no arguments, which is not what you
want.

> +@defun Value.fetch_lazy ()
> +If the @code{gdb.Value} object is currently a lazy value 
> +(@code{gdb.Value.is_lazy} is @code{True}) then the value is
                                            ^
Comma after the right parenthesis.

Okay with these changes.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFA] Python: PR/13327: expose laziness to Python
  2011-10-25 18:24 ` Eli Zaretskii
@ 2011-10-25 18:54   ` Paul Koning
  0 siblings, 0 replies; 3+ messages in thread
From: Paul Koning @ 2011-10-25 18:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, tromey


On Oct 25, 2011, at 2:16 PM, Eli Zaretskii wrote:

>> From: Paul Koning <paulkoning@comcast.net>
>> Date: Tue, 25 Oct 2011 13:38:20 -0400
>> Cc: Tom Tromey <tromey@redhat.com>
>> 
>> The documentation briefly touches on how lazy fetching works in the discussion of the is_lazy attribute, but it doesn't more fully discuss it as a topic of its own.  I could try to do so, in the introductory material for gdb.Value.  Should I do that?
> 
> No, I think what you wrote is good enough.
> 
>> Ok to commit?
> 
> A few comments to the documentation part:
> 
>> +@defvar Value.is_lazy
>> +This read-only boolean attribute is true if the value has not yet
> 
> "The attribute is true" sounds weird, doesn't it?  How about
> 
> The value of this read-only attribute is @code{True} if @code{Value}
> has not yet been fetched ...

What I wrote originally was copied from is_optimized_out.  But I like your wording better.  I made it "...if this @code{gdb.Value} has not yet..." which is the wording used in the other attributes directly above this one.

> ...
> Okay with these changes.

Thanks.  Committed that way.

	paul


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-10-25 18:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-25 17:43 [RFA] Python: PR/13327: expose laziness to Python Paul Koning
2011-10-25 18:24 ` Eli Zaretskii
2011-10-25 18:54   ` Paul Koning

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox