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