From: Hannes Domani Date: Mon, 3 Jun 2024 15:18:30 +0000 (+0200) Subject: Allow calling of convenience functions with python X-Git-Tag: binutils-2_43~562 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952;p=thirdparty%2Fbinutils-gdb.git 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 "", line 1, in 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 --- diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index dd17420b0b5..1ae26d73261 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