Re: [GD-Linux] Determining address of C++ member function at run-time...
Brought to you by:
vexxed72
From: Colin F. <cp...@ea...> - 2001-12-13 08:04:27
|
December 12th, 2001 Wednesday The primary reason I asked about finding the address of the implementation of non-static C++ class member functions was to satisfy my curiousity; I like to know how things work. But there was another reason... I built my own shared-library file (*.so), which had a few C and C++ static libraries (*.a) collected in there, in addition to my C++ object code (*.o). If you do "nm foo.so" and "objdump foo.so" you can learn a lot about the structure of the shared library file. In particular, you can see all of the function addresses (including non-static member functions). Okay, I also have an executable that loads my shared library at run-time. I have no source code for the executable, and it was stripped of symbols. When the executable invokes a method in my shared library, some part of the shared library causes a crash. There is code that successfully "unwinds" the call stack, so I get the addresses of all functions at the time of the crash. One of my co-workers wrote a Perl (ugh!) script that parses the stack trace and uses the output of "nm" and "objdump" to produce a friendly trace -- listing functions and line numbers! However, this script only works on regular executables with everything linked in. When a shared library is loaded, all of the code is re-located. In order to use the Perl script mentioned above, I had to determine where the code was placed in virtual memory. I picked an arbitrary function, printed its address at run-time, and compared this to the address indicated by "nm" or "objdump". I subtracted the difference in the Perl script, and now I get a valid stack trace for my shared library crash! ***NOTE: The function I chose was a straight C (extern "C" to avoid mangled names) function, whose address is trivial to print. *** Just to reassure myself that the addresses for the ***C++ non-static member functions*** were sane (in addition to the static member functions and straight C functions, whose addresses are trivial to print), I wanted to be able to print them -- thus the question I posted to this list. What I ended up doing was this: extern void MyFunction__8MyClassi(); printf( "%p", MyFunction__8MyClassi ); This prints the run-time address of the implementation of the non-static member function MyClass::MyFunction -- and my "extern" function prototype is completely artificial; it's just enough to keep the compiler from complaining about the symbol 'MyFunction__8MyClassi' being unknown... (...yet, heh, heh!) My fake prototype has to be a function (or something similar), but I don't need to match the arguments and return value of the actual function (with the specified mangled name). As I clearly mentioned in my initial post, I was willing to do any hack or frown-upon technique just to get the answer. This trick worked perfectly; I found that all of the code (C++ static and non-static functions alike) was relocated by the same constant offset at run-time. I'm still stuck with this crash, though. The problem is, part of the stack trace includes addresses that I can't explain. I can account for all of the code that is *DIRECTLY* contained in the shared library. But if the shared library itself loads even more shared libraries at run-time, and the crash is happening inside one of them...Uh, ohhh! Well, I won't bore you with more details of my problem (which is even more convoluted than I can explain here), but maybe I'll ask one last question: Can you use gdb to debug an executable- without-debugging-information just for the sake of debugging a shared library (whose symbols you *DO* have)? It's a crazy, multi-threaded, Java/C++ hybrid, with lots of library loading on both sides... Believe me, I completely agree that wanting to know the addresses of C++ member functions should never be necessary for any application! But I wanted to do some sanity checking before entertaining some wacky theories about the crashing. I'm not a Linux guru, and I haven't mastered debugging on that platform. Thanks, Ryan, for the interesting gcc compiler trick: printf("address of my_label is (%p).\n", &&my_label); I just like knowing that this can be done, even if I have no immediate plans to do this. --- Colin P. Fahey cp...@ea... |