I'm debugging a C++ program with GDB.
I have a pointer to an object of certain class. The pointer is declared to be of some super class which is extended by several sub-classes.
There is no fields in the object to specify the precise class type of this object but some virtual functions (e.g. bool is_xxx()) are defined to tell the class type at runtime.
Is there some way to tell the precise class type of an object in GDB without calling these virtual functions. Calling such functions in GDB may generate confusing result when the program is multi-threaded.
C++ has no direct method to check one object is an instance of some class type or not. In Java, we can get this kind of facility. In C++11, we can find one item called is_base_of<Base, T>. This will check if the given class is a base of the given object or not.
Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.
You can use both a structure and a class as base classes in the base list of a derived class declaration: If the derived class is declared with the keyword class , the default access specifier in its base list specifiers is private .
A base class's private members are never accessible directly from a derived class, but can be accessed through calls to the public and protected members of the base class.
Use ptype
. If you use it by itself, you get the declared type of the pointer:
(gdb) ptype ptr type = class SuperClass { // various members } *
To get the actual type of the object pointed to, set the "print object" variable:
(gdb) set print object on (gdb) ptype ptr type = /* real type = DerivedClass * */ class SuperClass { // various members } *
On my system ptype or whatis also only show the obvious.
(gdb) whatis pObject type = QObject *
But printing the first entry of the vtable helped me:
(gdb) p /a (*(void ***)pObject)[0] $4 = 0xb4b4cdf4 <QMessageBox::metaObject() const>
Here the pObject pointed to a QMessageBox which is derived from QObject. This only works if vtable-entry points to a method that is overridden by the derived class.
See also: Print C++ vtables using GDB
Edit: Printing only the pointer to the vtable works more reliable (though the output uses the mangled name and is not so readable):
(gdb) p /a (*(void ***)pObject) $5 = 0xb4af33a0 <_ZTV11QMessageBox+8>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With