Neuere Version von gdb ermöglichen das bequeme Parsen von VTables in C++.Drucken vtbl Funktionen jeder Klasse in GDB
sagen, dass ich diesen Beispielcode
class Matcher {
public:
virtual void match() { cout << "base";}
};
class NMatcher: public Matcher{
public:
void match() { cout << "derived";}
};
int main() {
Matcher* m = new Matcher();
m->match();
Matcher *m2 = new NMatcher();
m2->match();
}
ich die virtuelle Tabelle beiden Variablen in Haupt zugreifen kann über info vtbl ...
(gdb) info vtbl m
vtable for 'Matcher' @ 0x400ef0 (subobject @ 0x603010):
[0]: 0x400d9a <Matcher::match()>
Nun stellen Sie eine Situation, wo ich keine Variable im Umfang habe und Ich möchte die vtable eines virtuellen Objekts (oder einer reinen virtuellen Basisklasse) untersuchen. Dafür brauche ich kein Objekt. Die vtable ist statisch und sollte zugänglich sein.
einen Blick auf die Symbole sehen Lassen Sie die V-Tabelle zu finden:
(gdb) info variables .*Matcher
All variables matching regular expression ".*Matcher":
Non-debugging symbols:
0x0000000000400ec0 vtable for NMatcher
0x0000000000400ee0 vtable for Matcher
0x0000000000400ef8 typeinfo name for NMatcher
0x0000000000400f10 typeinfo for NMatcher
0x0000000000400f28 typeinfo name for Matcher
0x0000000000400f40 typeinfo for Matcher
ich nicht die aufgeführten Speicherplatz oben direkt verwenden können. Die virtuellen Methoden beginnen nicht am Anfang der vtable. Es gibt Offset und RTI für die ersten x Bytes. Im Fall von Matcher ist es 16, aber es kann jede beliebige Zahl sein:
(gdb) p *m
$22 = {
_vptr.Matcher = 0x400ef0 <vtable for Matcher+16>
}
In der Theorie kann ich den Speicherplatz des VTable direkt zugreifen und das Bytes manuell überprüfen:
(gdb) x /4a 0x0000000000400ee0
0x400ee0 <_ZTV7Matcher>: 0x0 0x400f40 <_ZTI7Matcher>
0x400ef0 <_ZTV7Matcher+16>: 0x400d9a <Matcher::match()>
Aber die ist zu schmerzhaft und ich würde gerne eine bequeme Art und Weise wissen, etwas zu tun in Richtung der (gdb) info vtbl 'vtable for Matcher'
Ich benutze GDB 7.8 aber jede Version wird tun.