Hello all,
I'm trying to implement a some kind of self-tracing/self-profiling feature for the shared
library which should be dlopen()ed and used by the application core. I'm started from
simple C program, like this (due to asm, this is x86-specific):
#include <stdio.h> #include <unistd.h>
#define rdtscll(val) asm volatile ("rdtsc" : "=A" (val))
FILE *f = NULL; int n, depth = -1; unsigned long long t; extern char *program_invocation_short_name;
void __profile_begin (void) __attribute__ ((constructor,no_instrument_function));
void __profile_end (void) __attribute__ ((destructor,no_instrument_function));
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
void __profile_begin (void) { char buf[1024];
snprintf (buf, sizeof (buf), "%s.prof.%d", program_invocation_short_name, getpid ());
f = fopen (buf, "w+");
fprintf (f, "Start of profiling for %s.\n", program_invocation_short_name);
}
void __profile_end (void) { fprintf (f, "End of profiling for %s.\n", program_invocation_short_name); fclose (f); }
void __cyg_profile_func_enter (void *func, void *caller) { rdtscll (t); depth++; for (n = 0; n < depth; n++) fprintf (f, " "); fprintf (f, "-> %p %llu\n", func, t); }
void __cyg_profile_func_exit (void *func, void *caller) { rdtscll (t); for (n = 0; n < depth; n++) fprintf (f, " "); fprintf (f, "<- %p %llu\n", func, t); depth--; }
void foo (void) { }
void bar (void) { }
int main (int argc, char *argv[]) { foo (); bar (); return 0; }
When compiling as a C program (with 'gcc -finstrument-functions -o selfprof selfprof.c'),
it works as expected, i.e. outputs into selfprof.prof.xxxxx something like this:
Start of profiling for selfprof. -> 0x80487b0 1521198259227518 -> 0x8048750 1521198259234666 <- 0x8048750 1521198259245630 -> 0x8048780 1521198259248230 <- 0x8048780 1521198259250462 <- 0x80487b0 1521198259252738 End of profiling for selfprof.
Here I can check that my code: - enters main() - enters foo() - leaves foo() - enters bar() - leaves bar() - leaves main()
But, when compiling the same code as C++ program (with 'g++ -finstrument-functions -o
selfprof selfprof.cxx', I've no function entry/exit marks in output:
Start of profiling for selfprof. End of profiling for selfprof.
I've checked this behaviour both with gcc 3.3.3 (preinstalled on my Fedora Core 2 system)
and with gcc 3.4.3 bootstrapped by myself from sources, but results are the same.
So, I'm confused. Can anybody explain me why this feature doesn't work for C++ programs ?
Thanks, Dmitry
P.S. Please also reply to me directly if possible.