问题
I am looking for a clever way to track function calls and returns.
I know I can use the debugger, but I would like a way to just have it print something out to the terminal when calling a function vs having to step through code.
I am thinking that I might be able to use the preprocessor, but I am not sure what would be the best way to go about this.
Or is there a way to use gdb to print out the information that would be useful, while not having to step through the code.
回答1:
Most compiler's allow you to inject an instrumentation function before and after the function call.
in msvc they are _penter and _pexit
nice article
http://www.drdobbs.com/184403601
in gcc you would use the -finstrument-functions
http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Code-Gen-Options.html
You can use debug libaries or map files to get more info.
回答2:
A quite intrussive solution is using RAII to control the scope of the function. This will have a great impact in performance, but will be quite explicit in the logs without requiring the user to add instrumentation in all possible code paths that may leave the function:
class ScopeLogger {
public:
ScopeLogger( std::string const & msg ) : msg(msg)
{ std::cout << "Enter: " << msg << std::endl; }
~ScopeLogger()
{ std::cout << "Exit: " << msg << std::endl; }
std::string msg;
};
#if DEBUG
#define FUNCTION(x) ScopeLogger l_##x##_scope(x);
#endif
void foo( int value ) {
FUNCTION( __FUNCTION__ );
if ( value > 10 ) throw std::exception;
std::cout << "." << std::endl;
}
int main() {
foo(0); // Enter: foo\n.\nExit: foo
foo(100); // Enter: foo\nExit: foo
}
If the code is single threaded, you might even want to add a static variable with some indentation level to ScopedLogger
without adding too much to the already heavy performance impact:
class ScopeLogger {
public:
ScopeLogger( std::string const & msg ) : msg(msg)
{ std::cout << std::string(indent++,' ') << "Enter: " << msg << std::endl; }
~ScopeLogger()
{ std::cout << std::string(--indent,' ') << "Exit: " << msg << std::endl; }
std::string msg;
static int indent;
};
int ScopeLogger::indent = 0;
回答3:
Since you are using GCC, you can also use linker function wrapping.
Link-Time Replacement / Wrapping
– GCC option: -Wl,--wrap,function_name
Basically, you can take a function called "function_name()" and wrap it with a function called "__wrap_function_name()". You can access the original function by calling "__real_function_name()".
回答4:
#define BEGIN_FUNC(X) printf("Function %s Entered",X)
#define END_FUNC(X) printf("Function %s End",X)
foo()
{
BEGIN_FUNC(__func__);
//Your code here
END_FUNC(__func__);
}
I think if you write a macro like above and use it for every function as described then you can get the logs on the terminal.
回答5:
You may want to look at Valgrind's Callgrind which can track function calls into a pretty graph. It will show function calls, but not the parameter or return values.
回答6:
Or is there a way to use gdb to print out the information that would be useful, while not having to step through the code
Yes. Set a breakpoint only at the functions that you actually care about. Use "continue" until you get to those functions or until your program crashes. Then use "backtrace" (or "bt") to get a stack trace.
回答7:
If you need to automate it, you might take a look at TARGET_ASM_FUNCTION_END_PROLOGUE
and TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
. These are compiler hooks that will let you specify pieces of assembly to be emitted along with the normal function prologue/epilogue -- in your case, you'd use them to emit a little assembly to log the entry/exit from the function in question. You could also look at FUNCTION_PROFILE
and/or PROFILE_HOOK
(e.g., at: http://gcc.gnu.org/onlinedocs/gccint/Function-Entry.html).
回答8:
There is a __FUNCTION__
(Reference) macro used to determine what method (in the format Class::Method
) you're in, but this is more of a manual process.
However, when I needed the same 'trace' information recently, I could not find a automatic method.
回答9:
Some time ago I listened to a talk about aspect oriented programming which includes what you want to achieve. Maybe a search for that term helps.
来源:https://stackoverflow.com/questions/3315248/c-c-need-a-clever-way-to-track-function-calls