Search code examples
c++gccgdbvtable

How to print virtual function of the VTable at a specific address when debugging with GDB


I am trying to print with GDB Debugger the name of a virtual function that exists in the VTable at a specific memory address.

Here is my simple code:

#include <iostream>
class Parent {
 public:
  virtual void Foo() {}
  virtual void FooNotOverridden() {}
};

class Derived : public Parent {
 public:
  void Foo() override {}
};

int main() {
  Parent p1, p2;
  Derived d1, d2;

  std::cout << "done" << std::endl;
}

Here is the followning info of gdb

0x8201d18 vtable for Derived:   0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x8201d20 vtable for Derived+8:     0x58    0x1d    0x20    0x08    0x00    0x00    0x00    0x00
0x8201d28 vtable for Derived+16:    0x8e    0x0c    0x00    0x08    0x00    0x00    0x00    0x00
0x8201d30 vtable for Derived+24:    0x82    0x0c    0x00    0x08    0x00    0x00    0x00    0x00
0x8201d38 vtable for Parent:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x8201d40 vtable for Parent+8 : 0x70    0x1d    0x20    0x08    0x00    0x00    0x00    0x00
0x8201d48 vtable for Parent+16 :    0x76    0x0c    0x00    0x08    0x00    0x00    0x00    0x00
0x8201d50 vtable for Parent+24 :    0x82    0x0c    0x00    0x08    0x00    0x00    0x00    0x00

and now with the following command

info symbol 0x8201d8e

i got this message

_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject 

Accoridng to my little experience at offset +8 it will be the pointer of the VTABLE and at offset +16 it will the pointer of the first method that exists inside the VTABLE.So if I got the value of the address 0x8201d28 which is 0x8201d8e I expect from the debugger to take an output like this

_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject 
 Derived::Foo() in section .text of a.out

and print the name of the function. But my problem is that the debugger doesn't print the name of the virtual function.I am so confused it should be there. What am I doing wrong there?


Solution

  • You need to load the function pointer from the vtable. Assuming the vtable is at address 0x555555755d48

    (gdb) info symbol 0x0000555555755d48
    vtable for Derived in section .data.rel.ro of /tmp/a.out
    

    I can obtain the name of the virtual function like this:

    (gdb) print ((void **)0x0000555555755d48)[2]
    $3 = (void *) 0x555555554bca <Derived::Foo()>
    

    Obviously, this will need debugging information. Exported vtables do not include names because they are identified by offset only (even if exported functions have names).