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
2010-08-05 00:55:59
i have the same question for you: how do i call the original C++ method? it seems like this method hides its name...
BruceBerry
2010-08-05 16:41:26
`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
2010-08-05 17:40:12
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
2010-08-05 18:54:28
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
2010-08-05 20:33:35
i got it to work, it was a bug! dlsym works as well. thank you!
BruceBerry
2010-08-16 03:26:02
+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
2010-08-05 02:47:06
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
2010-08-27 10:33:41