I have a 3rd party source code that I have to investigate. I want to see in what order the functions are called but I don't want to waste my time typing:
printf("Entered into %s", __FUNCTION__)
and
printf("Exited from %s", __FUNCTION__)
for each function, nor do I want to touch any source file.
Do you have any suggestions? Is there a compiler flag that automagically does this for me?
Clarifications to the comments:
EDIT: I found that 'frame' command in the gdb prompt prints the current frame (or, function name, you could say) at that point in time. Perhaps, it is possible (using gdb scripts) to call 'frame' command everytime a function is called. What do you think?
In C++, you can exit a program in these ways: Call the exit function. Call the abort function. Execute a return statement from main .
The exit () function is used to break out of a loop. This function causes an immediate termination of the entire program done by the operation system.
The function has been defined under the stdlib. h header file, which must be included while using the exit() function.
Besides the usual debugger and aspect-oriented programming techniques, you can also inject your own instrumentation functions using gcc's -finstrument-functions
command line options. You'll have to implement your own __cyg_profile_func_enter()
and __cyg_profile_func_exit()
functions (declare these as extern "C"
in C++).
They provide a means to track what function was called from where. However, the interface is a bit difficult to use since the address of the function being called and its call site are passed instead of a function name, for example. You could log the addresses, and then pull the corresponding names from the symbol table using something like objdump --syms
or nm
, assuming of course the symbols haven't been stripped from the binaries in question.
It may just be easier to use gdb
. YMMV. :)
You said "nor do I want to touch any source file"... fair game if you let a script do it for you?
Run this on all your .cpp files
sed 's/^{/{ENTRY/'
So that it transforms them into this:
void foo() {ENTRY // code here }
Put this in a header that can be #included by every unit:
#define ENTRY EntryRaiiObject obj ## __LINE__ (__FUNCTION__); struct EntryRaiiObject { EntryRaiiObject(const char *f) : f_(f) { printf("Entered into %s", f_); } ~EntryRaiiObject() { printf("Exited from %s", f_); } const char *f_; };
You may have to get fancier with the sed
script. You can also put the ENTRY macro anywhere else you want to probe, like some deeply nested inner scope of a function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With