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