These methods applies to static methods too.
Use convenience variable.
gdb.set_convenience_variable("tmp",
gdb.parse_and_eval("c").address
)
gdb.execute("print $tmp->f()")
If the type is known, you can do:
gdb.parse_and_eval("C::f")(
gdb.parse_and_eval("c").address
)
(alternatively use the mangled name _ZN1C1fEv
. nm --demangle
can be used for this for example)
If only the type of the target function is known, you can do
cftype=gdb.parse_and_eval("C::f").type # ← this is known
gdb.parse_and_eval("c")["f"].cast(cftype)(
gdb.parse_and_eval("c").address
)
Some flexibility is not allowed by gdb, but no guarantee:
cftype=gdb.parse_and_eval("* (void (*) (void*)) 0").type
gdb.parse_and_eval("c")["f"].cast(cftype)(
gdb.parse_and_eval("c").address
)
(if it's static function you don't need to "fake" it as void const*
, can also do directly in C++ code)
Example C++ code:
#include<iostream>
struct C{
int x;
void f() {
++x;
std::cout<<x<<"\n";
}
};
int main(){
C c{5};
c.f();
__builtin_trap();
}
In addition, if the struct is local however,
you'll have to apply some workarounds described in https://stackoverflow.com/a/70254108/5267751.
Example C++ code
int main(){
struct C{
int x;
void f() {
++x;
std::cout<<x<<"\n";
}
};
C c{5};
c.f();
__builtin_trap();
}
Example Python code
gdb.parse_and_eval("'main::C::f'")(gdb.parse_and_eval("c").address)
Alternatively use _ZZ4mainEN1C1fEv
.