The python scripting support is great. There is support for function call if a gdb.Value object is of type TYPE_CODE_FUNC. There is no support for method call yet if a gdb.Value object is of type TYPE_CODE_METHOD. In order to support the pretty-pritters for some classes, sometimes we need to call an method instead of just accessing some member fields. Thanks, Xun
Same for TYPE_CODE_INTERNAL_FUNCTION: (gdb) pi a=gdb.parse_and_eval('$_streq') (gdb) pi print a.type.code == gdb.TYPE_CODE_INTERNAL_FUNCTION True (gdb) pi a("1","2") Python Exception <type 'exceptions.RuntimeError'> Value is not callable (not TYPE_CODE_FUNC).:
I looked at the code and, indeed, class method invocation is barred. I suspect the reason for this is two-fold. Currently, in GDB we evaluate all the hairy C++ stuff in the evaluation parser. The Python inferior function call stuff just calls "call_function_by_hand". This causes, firstly, the separation from the "this" reference which is passed as a parameter to the function. If you remove the restriction in the code, GDB will complain about an incorrect number of arguments because the hidden "this" argument is missing. Secondly, all of the extra "shaping" for the function call is missing like overload resolution. So feature missing confirmed. I'm not sure when it will be worked on as it is a non-trivial issue. Perhaps when the C++ification progresses to the evaluation parser it might be possible without duplicating large amounts of code. There is a workaround available. You can use gdb.parse_and_eval to get the value by using it to call the function in question. This uses the evaluation parser and correctly sets up for the C++ function call. So something like: python f = gdb.parse_and_eval("someObject.someFunction()") This will call that function and return the value back to GDB as a Python value.
Use from a python pretty-printer is a bit convoluted, but it works: def to_string(self): gdb.set_convenience_variable('_tmp', self.val.reference_value()) return gdb.parse_and_eval('$_tmp.str()')
The master branch has been updated by Hannes Domani <ssbssa@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2e08907d0672711617f71ef4604df190106b992e commit 2e08907d0672711617f71ef4604df190106b992e Author: Hannes Domani <ssbssa@yahoo.de> Date: Thu Feb 8 20:09:25 2024 +0100 Allow calling of C++ methods from python Currently it's not possible to call C++ methods from python. Using this example: ``` class B { static int static_func (); int arg0_func (); int arg1_func (int arg1); int arg2_func (int arg1, int arg2); }; B *b_obj = new B; ``` Trying to call B::static_func gives this error: ``` (gdb) py b_obj = gdb.parse_and_eval('b_obj') (gdb) py print(b_obj['static_func']()) Traceback (most recent call last): File "<string>", line 1, in <module> RuntimeError: Value is not callable (not TYPE_CODE_FUNC). Error while executing Python code. ``` TYPE_CODE_METHOD was simply missing as a possible type in valpy_call, now the same is possible: ``` (gdb) py b_obj = gdb.parse_and_eval('b_obj') (gdb) py print(b_obj['static_func']()) 1111 ``` Note that it's necessary to explicitely add the this pointer as the first argument in a call of non-static methods: ``` (gdb) py print(b_obj['arg0_func']()) Traceback (most recent call last): File "<string>", line 1, in <module> gdb.error: Too few arguments in function call. Error while executing Python code. (gdb) py print(b_obj['arg0_func'](b_obj)) 198 ``` Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13326 Approved-By: Tom Tromey <tom@tromey.com>
Fixed.
The master branch has been updated by Hannes Domani <ssbssa@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952 commit f74da7b8b3d6f14ba9ad21b380f743e4bdc4e952 Author: Hannes Domani <ssbssa@yahoo.de> Date: Mon Jun 3 17:18:30 2024 +0200 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>
(In reply to vuvova from comment #1) > Same for TYPE_CODE_INTERNAL_FUNCTION: > > (gdb) pi a=gdb.parse_and_eval('$_streq') > (gdb) pi print a.type.code == gdb.TYPE_CODE_INTERNAL_FUNCTION > True > (gdb) pi a("1","2") > Python Exception <type 'exceptions.RuntimeError'> Value is not callable (not > TYPE_CODE_FUNC).: Now this is fixed as well.