[PATCH] Allow calling of convenience functions with python

Hannes Domani ssbssa@yahoo.de
Thu May 30 18:36:52 GMT 2024


As mentioned in PR13326, currently when you try to call a
convenience function with python, you get this error:

(gdb) py print(gdb.convenience_variable("_isvoid")(3))
Traceback (most recent call last):
  File "<string>", line 1, in <module>
RuntimeError: Value is not callable (not TYPE_CODE_FUNC or TYPE_CODE_METHOD).
Error while executing Python code.

So this extends valpy_call to handle TYPE_CODE_INTERNAL_FUNCTION as
well, making this possible:

(gdb) py print(gdb.convenience_variable("_isvoid")(3))
0
---
 gdb/python/py-value.c                 | 18 +++++++++++++-----
 gdb/testsuite/gdb.python/py-value.exp | 11 +++++++++++
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index dd17420b0b5..c844baa978b 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1210,11 +1210,13 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD)
+  if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD
+      && ftype->code () != TYPE_CODE_INTERNAL_FUNCTION)
     {
       PyErr_SetString (PyExc_RuntimeError,
 		       _("Value is not callable (not TYPE_CODE_FUNC"
-			 " or TYPE_CODE_METHOD)."));
+			 " or TYPE_CODE_METHOD"
+			 " or TYPE_CODE_INTERNAL_FUNCTION)."));
       return NULL;
     }
 
@@ -1248,9 +1250,15 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
     {
       scoped_value_mark free_values;
 
-      value *return_value
-	= call_function_by_hand (function, NULL,
-				 gdb::make_array_view (vargs, args_count));
+      value *return_value;
+      if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
+	return_value = call_internal_function(gdbpy_enter::get_gdbarch (),
+					      current_language,
+					      function, args_count, vargs);
+      else
+	return_value
+	  = call_function_by_hand (function, NULL,
+				   gdb::make_array_view (vargs, args_count));
       result = value_to_value_object (return_value);
     }
   catch (const gdb_exception &except)
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index aa674e8aa0d..8ab867a7088 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -377,6 +377,16 @@ proc test_inferior_function_call {} {
     gdb_test "python result2 = fp3(10)" ".*Too few arguments in function call.*"
 }
 
+proc test_convenience_function_call {} {
+    # Get convenience function with gdb.convenience_variable.
+    gdb_test "python print(gdb.convenience_variable('_isvoid')(2))" "0"
+    gdb_test "python print(gdb.convenience_variable('_strlen')('two'))" "3"
+
+    # Get convenience function with gdb.parse_and_eval.
+    gdb_test "python print(gdb.parse_and_eval('\$_isvoid')(3))" "0"
+    gdb_test "python print(gdb.parse_and_eval('\$_strlen')('three'))" "5"
+}
+
 # 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" \
@@ -782,6 +792,7 @@ test_value_in_inferior
 test_value_from_buffer
 test_value_sub_classes
 test_inferior_function_call
+test_convenience_function_call
 test_assign
 test_value_bytes
 test_value_after_death
-- 
2.35.1



More information about the Gdb-patches mailing list