diff options
author | Hannes Domani <ssbssa@yahoo.de> | 2024-06-03 17:18:30 +0200 |
---|---|---|
committer | Hannes Domani <ssbssa@yahoo.de> | 2024-06-03 17:18:30 +0200 |
commit | f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952 (patch) | |
tree | 51da3aa988b6f38d4eaec4bbe864be911ebca043 | |
parent | 8e8b2ab688b3d7e6035e6c782a2b42501d57c667 (diff) | |
download | gdb-f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952.zip gdb-f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952.tar.gz gdb-f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952.tar.bz2 |
Allow calling of convenience functions with python
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
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13326
Approved-By: Tom Tromey <tom@tromey.com>
-rw-r--r-- | gdb/python/py-value.c | 18 | ||||
-rw-r--r-- | 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 dd17420..1ae26d7 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 aa674e8..8ab867a 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 |