Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if an object is an instance of certain derived C++ class from a pointer to a base class in GDB?

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.

like image 920
user1101096 Avatar asked Dec 16 '11 01:12

user1101096


People also ask

How do you check if an object belongs to a certain class in C++?

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.

Can a derived class have pointer objects?

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.

How do you access base class members in a derived class?

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 .

Does base class have access to derived class?

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.


2 Answers

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 } * 
like image 105
Beta Avatar answered Sep 18 '22 11:09

Beta


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> 
like image 27
Joachim Avatar answered Sep 20 '22 11:09

Joachim