1

This is the same question as How to determine if an object is an instance of certain derived C++ class from a pointer to a base class in GDB? but to do the same from the gdb extension in Python.

Given the same example shown in an answer to that question:

#include <iostream>

class MyBase {
public:
  virtual int myMethod() = 0;
};

class MyDerived1 : public MyBase {
public:
  virtual int myMethod() { return 1; }
};

class MyDerived2 : public MyBase {
public:
  virtual int myMethod() { return 2; }
};

int main() {
  MyBase *myBase;
  MyDerived1 myDerived1;
  MyDerived2 myDerived2;
  myBase = &myDerived1;
  std::cout << myBase->myMethod() << std::endl;
  myBase = &myDerived2;
  std::cout << myBase->myMethod() << std::endl;
}

As mentioned in the response, I can do:

(gdb) b 24
Breakpoint 1 at 0x400a19: file derived.cc, line 24.
(gdb) run
Starting program: /home/ubuntu/c-test/derived/derived
1

Breakpoint 1, main () at derived.cc:24
24        myBase = &myDerived2;
(gdb) p *myBase
$1 = {_vptr.MyBase = 0x400c00 <vtable for MyDerived1+16>}
(gdb) set print object on
(gdb) p *myBase
$2 = (MyDerived1) {<MyBase> = {_vptr.MyBase = 0x400c00 <vtable for MyDerived1+16>}, <No data fields>}

So I can see that this is an instance of MyDerived1. But in Python, I get the following.

(gdb) python-interactive
>>> myBase = gdb.parse_and_eval("myBase")
>>> str(myBase.type)
'MyBase *'

How can I obtain the actual class in Python extension? The real objective here is to be able to cast the instance to the right derived class so I can pretty print the information specific to that derived class.

Community
  • 1
  • 1
hshib
  • 1,691
  • 1
  • 17
  • 22

1 Answers1

1

I can use the attribute dynamic_type as documented here:

— Variable: Value.dynamic_type

The dynamic type of this gdb.Value. This uses C++ run-time type information (RTTI) to determine the dynamic type of the value. If this value is of class type, it will return the class in which the value is embedded, if any. If this value is of pointer or reference to a class type, it will compute the dynamic type of the referenced object, and return a pointer or reference to that type, respectively. In all other cases, it will return the value's static type.

Note that this feature will only work when debugging a C++ program that includes RTTI for the object in question. Otherwise, it will just return the static type of the value as in ptype foo (see ptype).

So, I can get the derived class with:

>>> str(myBase.dynamic_type)
'MyDerived1 *'
hshib
  • 1,691
  • 1
  • 17
  • 22
  • Thank you for this great pointer. First, the current URL to the "dynamic_type" documentation is https://sourceware.org/gdb/onlinedocs/gdb/Values-From-Inferior.html. Second, here is how I extracted a derived class name from a base pointer from within a GDB/Python custom command script: "derived=gdb.parse_and_eval("*((My_Base_Class*)0x1006256700)").dynamic_type". is set to "class My_Derived_Class". gdb.parse_and_eval() returns a gdb.Value, off of which you can call "dynamic_type". – Moshe Rubin May 29 '23 at 13:29