When displaying object information for C++ class pointers or references, you have the option of viewing either static type information or dynamic type information.
The static type of a class pointer or reference is its type as defined in the source code, and thus cannot change. The dynamic type is the type of the object being referenced, before any casts were made to that object, and thus may change during program execution.
The debugger provides a debugger variable, $usedynamictypes, which allows you to control which form of the type information is displayed. The default value for this variable is true (1), which indicates that the dynamic type information is displayed. Setting this variable to false (0) instructs the debugger to display static type information. The output of the print, and whatis commands are affected.
The display of dynamic type information is supported for C++ class pointers and references. All other types display static type information. In addition, if the dynamic type of an object cannot be determined, the debugger defaults to the use of static type information.
This debugger functionality does not relax the C++ visibility rules regarding object member access through a pointer/reference (only members of the static type are accessible). For more information about the C++ visibility rules, see The Annotated C++ Reference Manual (by Margaret E. Ellis and Bjarne Stroustrup, 1990, Addison-Wesley Publishing Company).
In order for dynamic type information to be displayed, the object's static type must have at least one virtual function defined as part of its interface (either one it introduced or one it inherited from a base class). If no virtual functions are present for an object, only the static type information for that object is available for display.
The following example shows debugger output with $usedynamictypes set to 0 (false):
(idb) print $usedynamictypes
0
(idb) whatis *this
class HeavenlyBody {
const char* const _name;
class HeavenlyBody* _innerNeighbor;
class HeavenlyBody* _outerNeighbor;
class HeavenlyBody* _firstSatellite;
class HeavenlyBody* _lastSatellite;
virtual void printBody(const class HeavenlyBody*, unsigned int);
void printBodyAndItsSatellites(unsigned int) const;
HeavenlyBody(char*);
void addSatellite(class HeavenlyBody*);
const char* name(void) const;
unsigned int satelliteNumber(class HeavenlyBody*) const;
}
(idb) print *this
class HeavenlyBody {
_name = 0x805abe4="Moon";
_innerNeighbor = 0x0;
_outerNeighbor = 0x0;
_firstSatellite = 0x0;
_lastSatellite = 0x0;
}
The following example displays debugger output with $usedynamictypes set to 1 (true). The output is for the same object as the previous example, at the same point in program execution:
(idb) print $usedynamictypes
1
(idb) whatis *this
class Moon : Planet {
const Kilometers _radius;
Moon(char*, Megameters, Kilometers, class Planet*);
Kilometers radius(void) const;
virtual void printBody(unsigned int) const;
virtual ~Moon(void);
}
(idb) print *this
class Moon {
_radius = 1738;
_name = 0x805abe4="Moon"; // class Planet::HeavenlyBody
_innerNeighbor = 0x0; // class Planet::HeavenlyBody
_outerNeighbor = 0x0; // class Planet::HeavenlyBody
_firstSatellite = 0x0; // class Planet::HeavenlyBody
_lastSatellite = 0x0; // class Planet::HeavenlyBody
_primary = 0x806b4e0; // class Planet::Orbit
_distance = 384; // class Planet::Orbit
_name = 0x806b5c0="Earth 1"; // class Planet::Orbit
}