Print Address of Virtual Member Function

Print address of virtual member function

Currently there is no standard way of doing this in C++ although the information must be available somewhere. Otherwise, how could the program call the function? However, GCC provides an extension that allows us to retrieve the address of a virtual function:

void (A::*mfp)() = &A::func;
printf("address: %p", (void*)(b->*mfp));

...assuming the member function has the prototype void func().
This can be pretty useful when you want to cache the address of a virtual function or use it in generated code. GCC will warn you about this construct unless you specify -Wno-pmf-conversions. It's unlikely that it works with any other compiler.

What's the easiest way to print the address of a member function?

[Edited] As far as I know, there's no way to get the address of the function that actually will be called, regardless of virtualness. For virtual methods specifically, the method and destination of virtual dispatch is left to the implementation. However even for normal functions the function pointer may not be the actual code address of the function (although I suspect there are cases where it is).

get the real address(or index in vTable) of virtual member function

Don't give up so easily!

While the other answers are correct in saying that the C++ language doesn't allow you to do this in a portable way, there's an important factor in your particular case that may make this a more reasonable thing to do.

The key is that ID3DXFont is a COM interface and the exact binary details of how those work are specified separately from the language used to access them. So while C++ doesn't say what you'll find at the other end of that pointer, COM does say that there's a vtable there with an array of function pointers in a specified order and with a specified calling convention. This allows me to tell you that the index of the DrawText function is 314 (DrawTextA) or 15 (DrawTextW) and that this will still be true in Visual C++ 28.0 many years from now. Or in GCC 8.3.1 for that matter: since COM is a binary interface specification, all compilers are supposed to implement it the same way (if they claim to support COM).

Have a look at the second link below for a ready-made implementation of COM function hooking using two different methods. Approach#2 is the closest to what you're asking for but I think you may want to consider the first one instead because it involves less voodoo.

Sources:

[http://msdn.microsoft.com/en-us/library/ms680573(v=vs.85).aspx]
[http://www.codeproject.com/Articles/153096/Intercepting-Calls-to-COM-Interfaces]
[http://goodrender.googlecode.com/svn/trunk/include/d3dx9core.h]

How to print member function address in C++

I don't believe that there are any facilities provided by the language for doing this. There are overloads for operator << for streams to print out normal void* pointers, but member function pointers are not convertible to void*s. This is all implementation-specific, but typically member function pointers are implemented as a pair of values - a flag indicating whether or not the member function is virtual, and some extra data. If the function is a non-virtual function, that extra information is typically the actual member function's address. If the function is a virtual function, that extra information probably contains data about how to index into the virtual function table to find the function to call given the receiver object.

In general, I think this means that it's impossible to print out the addresses of member functions without invoking undefined behavior. You'd probably have to use some compiler-specific trick to achieve this effect.

Hope this helps!

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

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).



Related Topics



Leave a reply



Submit