Virtual base classes and dbghelp
Hi all,
As I mentioned in a previous thread (see 'Dbghelp, symbols and templates' in
microsoft.public.windbg), we created a powerful symbol engine using dbghelp
to dump the contents of the stack symbols when an exception occurs.
The engine is able to dereference and process UDT symbols up to their
highest base class. It also supports multiple inheritance. However, we are
having trouble with virtual inheritance. Documentation is very scarce in this
area (and virtual inheritance is very compiler specific). Suppose you have:
class A: virtual public B [...]
and a variable: A a1;
When the engine is processing symbol a1, it retrieves its address and goes
up in the hierarchy looking for base classes and fields. When the B base
class is found the following code is processed (stripped down of error
checking and processing to avoid clutter):
bool SymbolEngine::GetBaseClassLocation(DWORD64 moduleBase, DWORD typeIndex,
void** address, DWORD& offset, const kString& name)
{
// Obtain virtual base info
DWORD virtualBase = 0;
if(!::SymGetTypeInfo(::GetCurrentProcess(), moduleBase, typeIndex,
TI_GET_VIRTUALBASECLASS, &virtualBase ))
return false;
// Is this base class virtual?
if(virtualBase == 0)
{
// Non virtual : Offset in the parent UDT
if(!::SymGetTypeInfo(::GetCurrentProcess(), moduleBase, typeIndex,
TI_GET_OFFSET, &offset ) )
return false;
}
else
{
// Virtual: Virtual base pointer offset
if(!::SymGetTypeInfo(::GetCurrentProcess(), moduleBase, typeIndex,
TI_GET_VIRTUALBASEPOINTEROFFSET, &offset ) )
return false;
}
// Calculate the "real" address of the base class
// NOTE: This DOESN'T work with virtual inheritance!
*address = (void *)((DWORD_PTR)*address + offset);
// Success
return true;
}
If the base class is virtual (TI_GET_VIRTUALBASECLASS), its offset property
(TI_GET_OFFSET) does not work, and VirtualBasePointerOffset property
(TI_GET_VIRTUALBASEPOINTEROFFSET) should be used to determine the
displacement of the virtual base pointer inside the class data.
Of course, we only obtain an offset and we need the complete address to
process the base class. In normal inheritance, we just have to add the offset
to the symbol's address, but this doesn't work with virtual inheritance. The
retrieved offset is relative to the virtual base pointer of the base class.
So, how does one obtain the virtual base pointer and then access to the
virtual base table where the base class address is probably located? Unless
I'm making a huge confusion here?
Thanks in advance for any help,
Frederico Jer??nimo
NOTE: This is being cross-posted to several different newsgroups because it
covers several different areas (c++, dbghelp, debugger, etc.).