views:

74

answers:

2

I need to interpose on a method call in a C++ program (the class resides in a separate shared library). I thought I could use LD_PRELOAD, but i am not sure how this would work (i only found examples of C functions): is there a way to setup interposition for a single method without copying over any code from the interposed class implementation?

+1  A: 

It wouldn't be very portable, but you could write your interposing function in C and give it the mangled name of the C++ method. You would have to handle the this parameter explicitly, of course, but I think all ELF ABIs just treat it as an invisible first argument.

Zack
i have the same question for you: how do i call the original C++ method? it seems like this method hides its name...
BruceBerry
`dlsym(RTLD_NEXT, "mangled_name_of_function")`. By the way, neither my technique nor Tony's will work with virtual functions (but if this were a virtual function, you could just override it in a subclass, ne?)
Zack
I shouldn't override it because i shouldn't touch the client code which instantiates the object either. The method is not virtual, but apparently neither method works for me :-/
BruceBerry
Can you be specific about what happens instead of its working? I don't think I can deduce what's wrong without more information.
Zack
i got it to work, it was a bug! dlsym works as well. thank you!
BruceBerry
+1  A: 

Just create a file for the interposed code (making sure the implementation is out of line)... the namespaces, class name and function should be the same as for the method you want to intercept. In your class definition, don't mention the other methods you don't want to intercept. Remember that LD_PRELOAD needs a full path to the intercepting shared object.

For example, to intercept void X::fn1(), create a file libx2.cc with:

#include <iostream>

class X
{
  public:
    void X::fn1();
};

void X::fn1() { std::cout << "X2::fn()\n"; }

Then compile it up:

g++ -shared -o libx2.so libx2.cc

Then run ala

LD_PRELOAD=`pwd`/libx2.so ./libx_client

Cheers

Tony
this seems less hacky. i'll try it
BruceBerry
by the way, how do i call the original method from this new method?
BruceBerry
Yikes - only just noticed your question. In Linux (only), you can use dlsym(RTLD_NEXT, "name") - this explicitly says don't match the searching function, and find one in a later-loaded object. For other OS, I'm not sure, but there's got to be some web pages talking about portability from Linux, so a RTLD_NEXT search's a good bet. Doh - Zack covered all thank years ago... :-.
Tony