gdbの新しいバージョンでは、C++でのvtableの解析が便利です。 GDBの任意のクラスのvtbl関数を出力します。
は、私は今私がスコープ内に何の変数を持っていない状況を想像してみて、私はinfo vtbl ...
(gdb) info vtbl m
vtable for 'Matcher' @ 0x400ef0 (subobject @ 0x603010):
[0]: 0x400d9a <Matcher::match()>
を介して、主に存在する両方の変数の仮想テーブルにアクセスすることができ
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();
}
このサンプルコードを持っていると言います仮想オブジェクト(または純粋な仮想基本クラス)のvtableを調べたいと思います。そのために私は厳密にオブジェクトが必要なわけではありません。 vtableは静的で、アクセス可能でなければなりません。
のはvtableのを見つけるために記号を見てみましょう:
(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
は、私は上記の直接記載されているメモリ位置を使用することはできません。仮想メソッドは、vtableの先頭で開始しません。最初のxバイトにはRTIとRTIがあります。私は直接のvtableのメモリ位置にアクセスし、手動でバイトを検査することができる理論的に
(gdb) p *m
$22 = {
_vptr.Matcher = 0x400ef0 <vtable for Matcher+16>
}
:
(gdb) x /4a 0x0000000000400ee0
0x400ee0 <_ZTV7Matcher>: 0x0 0x400f40 <_ZTI7Matcher>
0x400ef0 <_ZTV7Matcher+16>: 0x400d9a <Matcher::match()>
をそれ整合の場合には16であるが、それは任意の数とすることができますあまりにも痛いですし、私は行に沿って何かを行う便利な方法を知りたいです(gdb) info vtbl 'vtable for Matcher'
私はGDB 7.8を使用していますが、どのバージョンでもできます。