public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* [rfc] Inferior Functions Calls and Python Values
@ 2009-09-09  8:23 Phil Muldoon
  2009-09-11  7:37 ` Phil Muldoon
  2009-10-07 19:37 ` ping - " Phil Muldoon
  0 siblings, 2 replies; 4+ messages in thread
From: Phil Muldoon @ 2009-09-09  8:23 UTC (permalink / raw)
  To: Project Archer

[-- Attachment #1: Type: text/plain, Size: 2206 bytes --]

This patch allows a Python value to become "callable", and to execute 
any underlying function by means of an inferior function call.  This is 
implemented purely as a function that is registered within the call 
field on the PyTypeObject. When a Python value is now called, the 
arguments are converted into a list of values. This value list, along 
with the value representing the function, is passed to the 
call_method_by_hand function.

Example

Given this function:

int func1(int a, int b)
{
     return a+b;
}

And loading this function into a value as shown (purely by 
demonstration, how the function is loaded into a value is up to you):

p/x func1
0x40048
python some_value = gdb.history(0)

Results in:

python print some_value(10,20)
30

This can also be applied within pretty printers. There is a test that 
demonstrates how to perform these calls within a pretty printer included 
with the patch.

This function does not test the sanity, or the number of arguments, or 
type checks the arguments before the function is passed to 
call_function_by_hand. It simply assembles the arguments, converts them 
from Python, passes them to the call function and then converts any GDB 
exceptions to Python exceptions.

Regards

Phil

ChangeLog

2009-09-09  Phil Muldoon <pmuldoon@redhat.com>

     * python/python-value.c (valpy_call): New function.
     (value_object_type): Register valpy_call as tp_call function.

Documentation ChangeLog

2009-09-09  Phil Muldoon <pmuldoon@redhat.com>

     * gdb.texinfo (Values From Inferior): Document inferior function
     calls on Python values.

Testsuite ChangeLog

2009-09-09  Phil Muldoon <pmuldoon@redhat.com>

     * gdb.python/python-value.c (func1): New function for inferior
     function call test.
     (func2): Likewise.
     * gdb.python/python-prettyprint.c (InferiorCall): New Class for
     pretty printer test.
     * gdb.python/python-prettyprint.py (pp_inferiorcall): New printer.
     (register_pretty_printers): Register pp_inferiorcall.
     * gdb.python/python-prettyprint.exp (run_lang_tests): Add inferior
     function call tests.
     * gdb.python/python-value.exp (test_inferior_function_call): New
     function.














[-- Attachment #2: pyval_inferiorcall.patch --]
[-- Type: text/plain, Size: 8566 bytes --]

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 374d113..2a3ae65 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19029,7 +19029,24 @@ can access its @code{foo} element with:
 bar = some_val['foo']
 @end smallexample
 
-Again, @code{bar} will also be a @code{gdb.Value} object.
+@code{bar} will be a @code{gdb.Value} object.
+
+Inferior values that represent a function or a function pointer can be
+called by supplying the arguments to the function in brackets, and
+calling the value in Python.  For example, if @code{some_val} is a
+@code{gdb.Value} instance holding a function or function pointer that
+takes two integers as arguments, you may execute that function and
+store its return value, if any, like so:
+
+@smallexample
+result = some_val (10,20)
+@end smallexample
+
+Again, @code{result} will be a @code{gdb.Value} object.
+
+The arguments provided must match the function prototype of the
+function or the call will fail.  Any errors generated from the
+inferior function call will be raised as an exception.
 
 The following attributes are provided:
 
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index 159c118..3a83e3f 100644
--- a/gdb/python/python-value.c
+++ b/gdb/python/python-value.c
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "dfp.h"
 #include "valprint.h"
+#include "infcall.h"
 
 #ifdef HAVE_PYTHON
 
@@ -346,6 +347,48 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
   return -1;
 }
 
+/* Called by the Python interpreter to perform an inferior function
+   call on the value in question.  */
+static PyObject *
+valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
+{
+  struct value *return_value;
+  Py_ssize_t args_count;
+  volatile struct gdb_exception except;
+  struct value *function = ((value_object *) self)->value;
+  struct value **vargs = NULL;
+
+  args_count = PyTuple_Size (args);
+  if (args_count > 0)
+    {
+      int i;
+      vargs =  alloca (sizeof (struct value *) * args_count);
+      for (i = 0; i < args_count; i++)
+	{
+	  vargs[i] = convert_value_from_python (PyTuple_GetItem (args, i));
+	  /* Check each argument converstion for any exceptions that
+	     may have been raised during converstion.  If any one
+	     of the arguments raised an exception during converstion,
+	     then the call should be aborted.  */
+	  if (PyErr_Occurred ())
+	    {
+	      PyErr_SetString (PyExc_RuntimeError,
+			       _("An error was encountered while "
+				 "converting an argument for an inferior "
+				 "function call.  Call aborted."));
+	      return NULL;
+	    }
+	}
+      }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      return_value = call_function_by_hand (function, args_count, vargs);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+  return value_to_value_object (return_value);
+}
+
 /* Called by the Python interpreter to obtain string representation
    of the object.  */
 static PyObject *
@@ -1070,7 +1113,7 @@ PyTypeObject value_object_type = {
   0,				  /*tp_as_sequence*/
   &value_object_as_mapping,	  /*tp_as_mapping*/
   0,				  /*tp_hash */
-  0,				  /*tp_call*/
+  (ternaryfunc)valpy_call,	  /*tp_call*/
   valpy_str,			  /*tp_str*/
   0,				  /*tp_getattro*/
   0,				  /*tp_setattro*/
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.c b/gdb/testsuite/gdb.python/python-prettyprint.c
index adf66b5..8d69d25 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.c
+++ b/gdb/testsuite/gdb.python/python-prettyprint.c
@@ -16,6 +16,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <string.h>
+#include <signal.h>
 
 struct s
 {
@@ -80,6 +81,26 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
     }
 };
 
+class InferiorCall
+{
+ private:
+  int value;
+
+ public:
+  InferiorCall ()
+    {
+      value = 0;
+    }
+
+   int add (int i)
+   {
+     value += i; /* Inferior breakpoint here.  */
+     if (value > 20)
+       raise (SIGABRT);
+
+     return value;
+   }
+};
 #endif
 
 typedef struct string_repr
@@ -200,7 +221,9 @@ main ()
   SSS& ref (sss);
 
   Derived derived;
-  
+  InferiorCall inf;
+  inf.add (10);
+
 #endif
 
   add_item (&c, 23);		/* MI breakpoint here */
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.exp b/gdb/testsuite/gdb.python/python-prettyprint.exp
index b2dc85d..24f06ad 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/python-prettyprint.exp
@@ -76,6 +76,13 @@ proc run_lang_tests {lang} {
 	gdb_test "print derived" \
 	    " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
 	gdb_test "print ns " "\"embedded\\\\000null\\\\000string\""
+	gdb_test "print inf" "Total is: 20.*"
+	gdb_test "print inf" "RuntimeError: The program being debugged was signaled while in a function called from GDB.*"
+	runto [gdb_get_line_number "break to inspect"]
+	gdb_test "b [gdb_get_line_number {Inferior breakpoint here} ${testfile}.c ]" \
+	".*Breakpoint.*"
+	gdb_test "print inf" "RuntimeError: The program being debugged stopped while in a function called from GDB.*"
+	runto [gdb_get_line_number "break to inspect"]
     }
 
     gdb_test "print x" " = $hex \"this is x\""
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index c3e0dc4..821317d 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
     def to_string (self):
         return "pp class name: " + self.val.type.tag
 
+class pp_inferiorcall:
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "Total is: %s" % (self.val['add'](self.val.address, 10))
+
 class pp_nullstr:
     def __init__(self, val):
         self.val = val
@@ -156,6 +163,8 @@ def register_pretty_printers ():
     pretty_printers_dict[re.compile ('^VirtualTest$')] =  pp_multiple_virtual
     pretty_printers_dict[re.compile ('^Vbase1$')] =  pp_vbase1
 
+    pretty_printers_dict[re.compile ('^InferiorCall$')] = pp_inferiorcall
+
     pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
     pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
     
diff --git a/gdb/testsuite/gdb.python/python-value.c b/gdb/testsuite/gdb.python/python-value.c
index f3d6284..bc3fb24 100644
--- a/gdb/testsuite/gdb.python/python-value.c
+++ b/gdb/testsuite/gdb.python/python-value.c
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <stdio.h>
+
 struct s
 {
   int a;
@@ -37,6 +39,16 @@ typedef struct s *PTR;
 
 enum e evalue = TWO;
 
+void func1 ()
+{
+  printf ("void function called\n");
+}
+
+int func2 (int arg1, int arg2)
+{
+  return arg1 + arg2;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -46,10 +58,13 @@ main (int argc, char *argv[])
   PTR x = &s;
   char st[17] = "divide et impera";
   char nullst[17] = "divide\0et\0impera";
+  void (*fp1) (void)  = &func1;
+  int  (*fp2) (int, int) = &func2;
 
   s.a = 3;
   s.b = 5;
   u.a = 7;
-
+  (*fp1) ();
+  (*fp2) (10,20);
   return 0;      /* break to inspect struct and union */
 }
diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp
index ccf438f..30aae27 100644
--- a/gdb/testsuite/gdb.python/python-value.exp
+++ b/gdb/testsuite/gdb.python/python-value.exp
@@ -218,6 +218,18 @@ proc test_value_in_inferior {} {
   gdb_test "python print repr(nullst)" "u'divide\\\\x00et'"
 }
 
+proc test_inferior_function_call {} {
+    global gdb_prompt hex
+    gdb_test "p/x fp1" " = $hex.*"
+    gdb_py_test_silent_cmd "python fp1 = gdb.history (0)" "get value from history" 1
+    gdb_test "python result = fp1()" ""
+    gdb_test "python print result" "void"
+    gdb_test "p/x fp2" " = $hex.*"
+    gdb_py_test_silent_cmd "python fp2 = gdb.history (0)" "get value from history" 1
+    gdb_test "python result2 = fp2(10,20)" ""
+    gdb_test "python print result2" "30"
+}
+
 # A few objfile tests.
 proc test_objfiles {} {
     gdb_test "python\nok=False\nfor file in gdb.objfiles():\n  if 'python-value' in file.filename:\n    ok=True\nprint ok\nend" "True"
@@ -300,5 +312,6 @@ if ![runto_main] then {
 }
 
 test_value_in_inferior
+test_inferior_function_call
 test_value_after_death
 test_cast_regression

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

* Re: [rfc] Inferior Functions Calls and Python Values
  2009-09-09  8:23 [rfc] Inferior Functions Calls and Python Values Phil Muldoon
@ 2009-09-11  7:37 ` Phil Muldoon
  2009-10-08 20:41   ` Tom Tromey
  2009-10-07 19:37 ` ping - " Phil Muldoon
  1 sibling, 1 reply; 4+ messages in thread
From: Phil Muldoon @ 2009-09-11  7:37 UTC (permalink / raw)
  To: Project Archer

[-- Attachment #1: Type: text/plain, Size: 626 bytes --]

On 09/09/2009 09:22 AM, Phil Muldoon wrote:
> This patch allows a Python value to become "callable", and to execute 
> any underlying function by means of an inferior function call.  This 
> is implemented purely as a function that is registered within the call 
> field on the PyTypeObject. When a Python value is now called, the 
> arguments are converted into a list of values. This value list, along 
> with the value representing the function, is passed to the 
> call_method_by_hand function.
>

I've regenerated this patch against the new Python 8.3 names/merge that 
was committed last night. Attached.

Regards

Phil

[-- Attachment #2: pyval_inferiorcall_rename.patch --]
[-- Type: text/plain, Size: 8458 bytes --]

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 0e0c288..be06b4e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19083,7 +19083,24 @@ can access its @code{foo} element with:
 bar = some_val['foo']
 @end smallexample
 
-Again, @code{bar} will also be a @code{gdb.Value} object.
+@code{bar} will be a @code{gdb.Value} object.
+
+Inferior values that represent a function or a function pointer can be
+called by supplying the arguments to the function in brackets, and
+calling the value in Python.  For example, if @code{some_val} is a
+@code{gdb.Value} instance holding a function or function pointer that
+takes two integers as arguments, you may execute that function and
+store its return value, if any, like so:
+
+@smallexample
+result = some_val (10,20)
+@end smallexample
+
+Again, @code{result} will be a @code{gdb.Value} object.
+
+The arguments provided must match the function prototype of the
+function or the call will fail.  Any errors generated from the
+inferior function call will be raised as an exception.
 
 The following attributes are provided:
 
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 159c118..3a83e3f 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "dfp.h"
 #include "valprint.h"
+#include "infcall.h"
 
 #ifdef HAVE_PYTHON
 
@@ -346,6 +347,48 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
   return -1;
 }
 
+/* Called by the Python interpreter to perform an inferior function
+   call on the value in question.  */
+static PyObject *
+valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
+{
+  struct value *return_value;
+  Py_ssize_t args_count;
+  volatile struct gdb_exception except;
+  struct value *function = ((value_object *) self)->value;
+  struct value **vargs = NULL;
+
+  args_count = PyTuple_Size (args);
+  if (args_count > 0)
+    {
+      int i;
+      vargs =  alloca (sizeof (struct value *) * args_count);
+      for (i = 0; i < args_count; i++)
+	{
+	  vargs[i] = convert_value_from_python (PyTuple_GetItem (args, i));
+	  /* Check each argument converstion for any exceptions that
+	     may have been raised during converstion.  If any one
+	     of the arguments raised an exception during converstion,
+	     then the call should be aborted.  */
+	  if (PyErr_Occurred ())
+	    {
+	      PyErr_SetString (PyExc_RuntimeError,
+			       _("An error was encountered while "
+				 "converting an argument for an inferior "
+				 "function call.  Call aborted."));
+	      return NULL;
+	    }
+	}
+      }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      return_value = call_function_by_hand (function, args_count, vargs);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+  return value_to_value_object (return_value);
+}
+
 /* Called by the Python interpreter to obtain string representation
    of the object.  */
 static PyObject *
@@ -1070,7 +1113,7 @@ PyTypeObject value_object_type = {
   0,				  /*tp_as_sequence*/
   &value_object_as_mapping,	  /*tp_as_mapping*/
   0,				  /*tp_hash */
-  0,				  /*tp_call*/
+  (ternaryfunc)valpy_call,	  /*tp_call*/
   valpy_str,			  /*tp_str*/
   0,				  /*tp_getattro*/
   0,				  /*tp_setattro*/
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.c b/gdb/testsuite/gdb.python/py-prettyprint.c
index bf41ebc..ac5e33f 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.c
+++ b/gdb/testsuite/gdb.python/py-prettyprint.c
@@ -16,6 +16,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <string.h>
+#include <signal.h>
 
 struct s
 {
@@ -80,6 +81,26 @@ class Derived : public Vbase1, public Vbase2, public Vbase3
     }
 };
 
+class InferiorCall
+{
+ private:
+  int value;
+
+ public:
+  InferiorCall ()
+    {
+      value = 0;
+    }
+
+   int add (int i)
+   {
+     value += i; /* Inferior breakpoint here.  */
+     if (value > 20)
+       raise (SIGABRT);
+
+     return value;
+   }
+};
 #endif
 
 struct substruct {
@@ -223,7 +244,9 @@ main ()
   SSS& ref (sss);
 
   Derived derived;
-  
+  InferiorCall inf;
+  inf.add (10);
+
 #endif
 
   add_item (&c, 23);		/* MI breakpoint here */
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp
index 287a5d3..c02f92e 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/py-prettyprint.exp
@@ -76,6 +76,13 @@ proc run_lang_tests {lang} {
 	gdb_test "print derived" \
 	    " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
 	gdb_test "print ns " "\"embedded\\\\000null\\\\000string\""
+	gdb_test "print inf" "Total is: 20.*"
+	gdb_test "print inf" "RuntimeError: The program being debugged was signaled while in a function called from GDB.*"
+	runto [gdb_get_line_number "break to inspect"]
+	gdb_test "b [gdb_get_line_number {Inferior breakpoint here} ${testfile}.c ]" \
+	".*Breakpoint.*"
+	gdb_test "print inf" "RuntimeError: The program being debugged stopped while in a function called from GDB.*"
+	runto [gdb_get_line_number "break to inspect"]
     }
 
     gdb_test "print x" " = $hex \"this is x\""
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py
index 2f070d8..8dc3877 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.py
+++ b/gdb/testsuite/gdb.python/py-prettyprint.py
@@ -92,6 +92,13 @@ class pp_vbase1:
     def to_string (self):
         return "pp class name: " + self.val.type.tag
 
+class pp_inferiorcall:
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "Total is: %s" % (self.val['add'](self.val.address, 10))
+
 class pp_nullstr:
     def __init__(self, val):
         self.val = val
@@ -169,6 +176,8 @@ def register_pretty_printers ():
     pretty_printers_dict[re.compile ('^VirtualTest$')] =  pp_multiple_virtual
     pretty_printers_dict[re.compile ('^Vbase1$')] =  pp_vbase1
 
+    pretty_printers_dict[re.compile ('^InferiorCall$')] = pp_inferiorcall
+
     pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
     pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
     
diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c
index f3d6284..bc3fb24 100644
--- a/gdb/testsuite/gdb.python/py-value.c
+++ b/gdb/testsuite/gdb.python/py-value.c
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <stdio.h>
+
 struct s
 {
   int a;
@@ -37,6 +39,16 @@ typedef struct s *PTR;
 
 enum e evalue = TWO;
 
+void func1 ()
+{
+  printf ("void function called\n");
+}
+
+int func2 (int arg1, int arg2)
+{
+  return arg1 + arg2;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -46,10 +58,13 @@ main (int argc, char *argv[])
   PTR x = &s;
   char st[17] = "divide et impera";
   char nullst[17] = "divide\0et\0impera";
+  void (*fp1) (void)  = &func1;
+  int  (*fp2) (int, int) = &func2;
 
   s.a = 3;
   s.b = 5;
   u.a = 7;
-
+  (*fp1) ();
+  (*fp2) (10,20);
   return 0;      /* break to inspect struct and union */
 }
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 93cddc7..691ba1f 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -255,6 +255,18 @@ proc test_value_in_inferior {} {
   gdb_test "python print repr(nullst)" "u'divide\\\\x00et'"
 }
 
+proc test_inferior_function_call {} {
+    global gdb_prompt hex
+    gdb_test "p/x fp1" " = $hex.*"
+    gdb_py_test_silent_cmd "python fp1 = gdb.history (0)" "get value from history" 1
+    gdb_test "python result = fp1()" ""
+    gdb_test "python print result" "void"
+    gdb_test "p/x fp2" " = $hex.*"
+    gdb_py_test_silent_cmd "python fp2 = gdb.history (0)" "get value from history" 1
+    gdb_test "python result2 = fp2(10,20)" ""
+    gdb_test "python print result2" "30"
+}
+
 # A few objfile tests.
 proc test_objfiles {} {
     gdb_test "python\nok=False\nfor file in gdb.objfiles():\n  if 'py-value' in file.filename:\n    ok=True\nprint ok\nend" "True"
@@ -337,5 +349,6 @@ if ![runto_main] then {
 }
 
 test_value_in_inferior
+test_inferior_function_call
 test_value_after_death
 test_cast_regression

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

* ping - Re: [rfc] Inferior Functions Calls and Python Values
  2009-09-09  8:23 [rfc] Inferior Functions Calls and Python Values Phil Muldoon
  2009-09-11  7:37 ` Phil Muldoon
@ 2009-10-07 19:37 ` Phil Muldoon
  1 sibling, 0 replies; 4+ messages in thread
From: Phil Muldoon @ 2009-10-07 19:37 UTC (permalink / raw)
  To: Project Archer

On 09/09/2009 09:22 AM, Phil Muldoon wrote:
> This patch allows a Python value to become "callable", and to execute 
> any underlying function by means of an inferior function call.  This 
> is implemented purely as a function that is registered within the call 
> field on the PyTypeObject. When a Python value is now called, the 
> arguments are converted into a list of values. This value list, along 
> with the value representing the function, is passed to the 
> call_method_by_hand function.


It's been about a month, so ping on this patch

Regards

Phil

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

* Re: [rfc] Inferior Functions Calls and Python Values
  2009-09-11  7:37 ` Phil Muldoon
@ 2009-10-08 20:41   ` Tom Tromey
  0 siblings, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2009-10-08 20:41 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Project Archer

Sorry about the delay on this.
Thanks for pinging.

Phil> +Inferior values that represent a function or a function pointer can be
Phil> +called by supplying the arguments to the function in brackets, and
Phil> +calling the value in Python.

This reads strangely to me.  For one thing, they aren't brackets, but
parentheses.

How about:

A @code{gdb.Value} that represents a function or a function pointer is a
callable Python object.

Phil> +The arguments provided must match the function prototype of the
Phil> +function or the call will fail.  Any errors generated from the
Phil> +inferior function call will be raised as an exception.
 
I think, "raise as a Python exception", just to be clear.
And, what would an error be?

Does Python API do no argument type-checking at all?
Or does call_function_by_hand do this?

Phil> +	  vargs[i] = convert_value_from_python (PyTuple_GetItem (args, i));

It seems like you should check the result of PyTuple_GetItem before
calling.  convert_value_from_python asserts that the argument is
non-null.

Phil> +	  /* Check each argument converstion for any exceptions that

Typo, "conversion" .. it appears a few times.

Phil> +	  if (PyErr_Occurred ())
Phil> +	    {
Phil> +	      PyErr_SetString (PyExc_RuntimeError,
Phil> +			       _("An error was encountered while "
Phil> +				 "converting an argument for an inferior "
Phil> +				 "function call.  Call aborted."));
Phil> +	      return NULL;
Phil> +	    }

You don't need this, just:

    if (vargs[i] == NULL)
      return NULL;

Phil> +  (ternaryfunc)valpy_call,	  /*tp_call*/

Space after close paren.

Phil> +#include <signal.h>
[...]
Phil> +       raise (SIGABRT);

I'm not sure this is ok.
Do any other gdb tests do this?


What happens if you make an inferior function call and the inferior hits
a breakpoint during the call?

Tom

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

end of thread, other threads:[~2009-10-08 20:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-09  8:23 [rfc] Inferior Functions Calls and Python Values Phil Muldoon
2009-09-11  7:37 ` Phil Muldoon
2009-10-08 20:41   ` Tom Tromey
2009-10-07 19:37 ` ping - " Phil Muldoon

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).