C/C++ need a clever way to track function calls - c++

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.

Most compilers allow you to inject an instrumentation function before and after the function call.
In MSVC they are _penter and _pexit. A nice article: http://www.drdobbs.com/184403601.
In GCC you would use the -finstrument-functions option, see the docs.
You can use debug libaries or map files to get more info.

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;

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()".

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

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.

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.

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

Below is an example illustrating the GCC side of the answer by Jonathan Fischoff.
Here we call external tool addr2line to print the location as functionName at /path/to/file.cpp:line instead of simply the address. I've tried using dladdr for this (as suggested in a comment to the answer linked above), but it returned only null pointers in dli_sname for me.
This approach of resolving the addresses has some drawbacks:
It's slow due to fork/execve/file read.
It needs exact file path to the binary containing the address, so the simple code below can't print symbols in shared libraries.
// Instrumentation
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void __attribute__((no_instrument_function))
log_func(const void* funcAddr, const char* action, const void* callSite)
{
char cmd[50];
snprintf(cmd, sizeof cmd, "addr2line -Cpfe /proc/%d/exe %p", getpid(), funcAddr);
fprintf(stderr, "%p %s %p ", callSite, action, funcAddr);
system(cmd);
}
extern "C" void __attribute__((no_instrument_function))
__cyg_profile_func_enter(void* this_fn, void* call_site)
{
log_func(this_fn, "->", call_site);
}
extern "C" void __attribute__((no_instrument_function))
__cyg_profile_func_exit(void* this_fn, void* call_site)
{
log_func(this_fn, "<-", call_site);
}
// Actual code we're tracing
#include <iostream>
struct Test
{
Test() { std::cout << "Hi, I'm Test constructor\n"; }
void method() const { std::cout << "And I'm Test method\n"; }
};
int main()
{
std::cout << "Hello, my name is main\n";
Test test;
test.method();
}
Compilation and running:
$ g++ test.cpp -o test -g -finstrument-functions && time ./test
0x8048b0b -> 0x804899b _GLOBAL__sub_I___cyg_profile_func_enter at /tmp/test.cpp:41
0x80489c4 -> 0x804890b __static_initialization_and_destruction_0(int, int) at /tmp/test.cpp:41
0x80489c4 <- 0x804890b __static_initialization_and_destruction_0(int, int) at /tmp/test.cpp:41
0x8048b0b <- 0x804899b _GLOBAL__sub_I___cyg_profile_func_enter at /tmp/test.cpp:41
0xf7a0de71 -> 0x804886a main at /tmp/test.cpp:37
Hello, my name is main
0x80488b1 -> 0x80489de Test::Test() at /tmp/test.cpp:32
Hi, I'm Test constructor
0x80488b1 <- 0x80489de Test::Test() at /tmp/test.cpp:32
0x80488c0 -> 0x8048a4a Test::method() const at /tmp/test.cpp:33
And I'm Test method
0x80488c0 <- 0x8048a4a Test::method() const at /tmp/test.cpp:33
0xf7a0de71 <- 0x804886a main at /tmp/test.cpp:37
real 0m0.062s
user 0m0.054s
sys 0m0.008s

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.

Related

Enable debug print statements if compiled with debug flag

Let's say I have a project with many functions. For debugging purpopses, I want each one of them print out a diagnostic message (or a few) when called:
int f(int arg) {
cerr << "f() called with argument" << arg << endl;
int ret = 42;
cerr << "f() returned " << ret << endl;
return ret;
}
and so on. In one function, there may be as many as five to six messages printed out on cerr. I want to be able to disable them unless a debug flag (like NDEBUG) is set. One thing I could do is wrap each cerr statement with an if-statement.
#ifdef NDEBUG
const bool DEBUG_ON = true;
#else
const bool DEBUG_ON = false;
#endif
int f(int arg) {
if (DEBUG_ON) {
cerr << "f() called with argument" << arg << endl;
}
int ret = 42;
if (DEBUG_ON) {
cerr << "f() returned " << ret << endl;
}
return ret;
}
But it can get really tedious and, in the end, virtually unreadable with a couple dozens of such statements. My idea was to replace cerr with a custom object with an overloaded << operator which would send any arguments passed to it "into the void" like this:
class NullOutStream {
public:
NullOutStream operator<<(...) {
return *this;
}
};
NullOutStream debug_out;
#ifdef NDEBUG
#define debug_out cerr
#else
#define debug_out debug_out
#endif
Although it works perfectly, it doesn't seem very elegant. Is there a standard/nicer way to accomplish this?
There is no "standard" way to do this. There are many logging/assertion libraries that deal with similar issues, and there are different approaches to solve this. A few things to keep in mind:
It may or may not be desirable to keep the side effects of your log statement (as yours does). For example, if you did something like this:
debug_out << ++i;
This would increment i no matter whether you are in debug mode or not. This is probably desirable in this case. Conversely, if you do this:
debug_out << some_object.expensive_to_string_operation();
This would call expensive_to_string_operation() even when you are not in debug mode. This is probably not desirable in this case.
This would not happen if you used printf-style debug macro, e.g. something like this:
#ifdef NDEBUG
#define logf(...)
#else
#define logf(...) printf(__VA_ARGS__)
#endif
The reason being that when in non-debug mode, the arguments would be removed by the preprocessor.
You may want to do other things before or after each log statement, e.g. record a time stamp, flush a log file etc. It is possible to do this with streams by using destructor tricks, but it is more complicated to implement. It is much easier to do this using a function call, e.g. something like this:
#define log(msg) printf("%s: %s\n", timestamp(), msg)
You may want to record file name / line number with your logs. Again, this is easier to do with a function call than with a stream.
Streams may be better if you want custom formatting by object type - the printf interface doesn't lend itself to that very well.
I would recommend to have a look at some existing logging libraries to get an idea of different approaches. I suggest looking at Google's glog library because it has an interesting combination of using streams while retaining the ability to do 'per call' things (e.g. record time stamps, line numbers etc).

Define then Undefine Preprocessor Variables within Macro

I would like to create a macro like the following, which would be used to create two functions: one with debugging enabled and one without debugging enabled.
#define MakeDebuggerFunction(funName, funContents)\
void funName() funContents\
#define DEBUGGING\
void funName ## _debugging() funContents\
#undef DEBUGGING
And the way this would be used would be like the following
MakeDebuggerFunction(DoWork,
{
std::cout << "Doing Work" << std::endl;
#ifdef DEBUGGING
std::cout << "Printing Verbose" << std::endl;
#endif
}
)
This would result in two functions: DoWork and DoWork_debugging. Where both functions would have the same exact "guts" of the code for that function, but the debugging function would also have some verbose printing added.
The reason I want both functions created is because my GUI application has a "developer mode" which I can use when I'm out of the office and onsite with customers, where I don't have the luxury of a true debugging environment.
Many of these functions are also very processing intensity so I want to avoid doing something like adding a permanent if(DeveloperMode) {} statement wrapping my verbose code.
Any help/suggestions I can get would be greatly appreciated.
I think this is what #Justin was suggesting
I would make my wrapper function like this:
void DoWork_Wrapper()
{
if (DeveloperMode)
DoWork(..., true);
else
DoWork(...., false);
}
and the worker function would be:
void DoWork(..., bool DeveloperMode)
{
/// do some stuff
if (DeveloperMode)
/// print verbose
}
So when I make the call to DoWork(..., false) the compiler has already optimized out the if-statements?
How about doing it this way. You can make your debug function inline and it will be completely transparent. Of course you will have to work around more complex debug messages and adjust your debug function appropriately. It would be much better than making duplicates of your functions.
void debug(string s) {
if (DeveloperMode) {
std::cout << s << "\n";
}
}
std::cout << "Doing Work" << std::endl;
debug("Printing Verbose");
Or you can use one of the looging libraries out there. E.g. Log4c.
I'm not sure if this is exactly what you want but if you can compile one version with debugging enabled and one without you can just add a DEBUGGING compile flag to the debugging one and do the following
#ifdef DEBUGGING
#define debugPrint(verboseMessage) \
std::cout << verboseMessage << std::endl;
#else
#define debugPrint(verboseMessage)
#endif
This will make it so you can always call this macro and if debugging is on it will actually print your message, otherwise nothing will happen.
HTH!

Getting a function name (__func__) from a class T and a pointer to member function void(T::*pmf)()

Is it possible to write some f() template function that takes a type T and a pointer to member function of signature void(T::*pmf)() as (template and/or function) arguments and returns a const char* that points to the member function's __func__ variable (or to the mangled function name)?
EDIT: I am asked to explain my use-case. I am trying to write a unit-test library (I know there is a Boost Test library for this purpose). And my aim is not to use any macros at all:
struct my_test_case : public unit_test::test {
void some_test()
{
assert_test(false, "test failed.");
}
};
My test suite runner will call my_test_case::some_test() and if its assertion fails, I want it log:
ASSERTION FAILED (&my_test_case::some_test()): test failed.
I can use <typeinfo> to get the name of the class but the pointer-to-member-function is just an offset, which gives no clue to the user about the test function being called.
It seems like what you are trying to achieve, is to get the name of the calling function in assert_test(). With gcc you can use
backtace to do that. Here is a naive example:
#include <iostream>
#include <execinfo.h>
#include <cxxabi.h>
namespace unit_test
{
struct test {};
}
std::string get_my_caller()
{
std::string caller("???");
void *bt[3]; // backtrace
char **bts; // backtrace symbols
size_t size = sizeof(bt)/sizeof(*bt);
int ret = -4;
/* get backtrace symbols */
size = backtrace(bt, size);
bts = backtrace_symbols(bt, size);
if (size >= 3) {
caller = bts[2];
/* demangle function name*/
char *name;
size_t pos = caller.find('(') + 1;
size_t len = caller.find('+') - pos;
name = abi::__cxa_demangle(caller.substr(pos, len).c_str(), NULL, NULL, &ret);
if (ret == 0)
caller = name;
free(name);
}
free(bts);
return caller;
}
void assert_test(bool expression, const std::string& message)
{
if (!expression)
std::cout << "ASSERTION FAILED " << get_my_caller() << ": " << message << std::endl;
}
struct my_test_case : public unit_test::test
{
void some_test()
{
assert_test(false, "test failed.");
}
};
int main()
{
my_test_case tc;
tc.some_test();
return 0;
}
Compiled with:
g++ -std=c++11 -rdynamic main.cpp -o main
Output:
ASSERTION FAILED my_test_case::some_test(): test failed.
Note: This is a gcc (linux, ...) solution, which might be difficult to port to other platforms!
TL;DR: It is not possible to do this in a reasonably portable way, other than using macros. Using debug symbols is really a hard solution, which will introduce a maintenance and architecture problem in the future, and a bad solution.
The names of functions, in any form, is not guaranteed to be stored in the binary [or anywhere else for that matter]. Static free functions certainly won't have to expose their name to the rest of the world, and there is no real need for virtual member functions to have their names exposed either (except when the vtable is formed in A.c and the member function is in B.c).
It is also entirely permissible for the linker to remove ALL names of functions and variables. Names MAY be used by shared libraries to find functions not present in the binary, but the "ordinal" way can avoid that too, if the system is using that method.
I can't see any other solution than making assert_test a macro - and this is actually a GOOD use-case of macros. [Well, you could of course pass __func__ as a an argument, but that's certainly NOT better than using macros in this limited case].
Something like:
#define assert_test(x, y) do_assert_test(x, y, __func__)
and then implment do_assert_test to do what your original assert_test would do [less the impossible bit of figuring out the name of the function].
If it's unit tests, and you can be sure that you will always do this with debug symbols, you could solve it in a very non-portable way by building with debug symbols and then using the debug interface to find the name of the function you are currently in. The reason I say it's non-portable is that the debug API for a given OS is not standard - Windows does it one way, Linux another, and I'm not sure how it works in MacOS - and to make matters worse, my quick search on the subject seems to indicate that reading debug symbols doesn't have an API as such - there is a debug API that allows you to inspect the current process and figure out where you are, what the registers contain, etc, but not to find out what the name of the function is. So that's definitely a harder solution than "convince whoever needs to be convinced that this is a valid use of a macro".

Elegant approach to error logging in C++11 application?

I'm working on a small C++11 application (an SDL2 game) and i'm having a hard time "porting" some of my object-oriented knowledge from PHP/Java to C++. For example, in order to create an elegant error logging approach, i would create a class with various adapters and centralize logging there. I already did that in C++, but i have no idea on how my classes should be using the Logger class.
In Java and PHP, i would use dependency injection, and put the Logger as a class member variable in them. But in C++, what's the proper way? I don't really think that going static would be nice.
Oh man.
To me logging is similar to date/time handling: the basic case is trivial, but anything more than trivial is extremely complicated: no middle ground.
Let me advise you to look into a general purpose logging library such as Pantheios or Boost.Log.
The reason why I advice for this approach as opposed to making "your own effort", is that I know first hand how the "logging situation" goes:
you start with a simple "write to file" or "write to screen"
then you need to also log to another device
then you want to filter out severity levels
then you want to send your logs via pipes
then you want to turn off logging
And it all becomes very, very difficult, and the logging classes start polluting your code.
So, like I said: based on my limited experience, I would encourage you to look into the suggested libraries.
Good luck.
Edit: Boost.Log examples
Just for completeness of the post (refer to page for details).
Trivial case:
#include <boost/log/trivial.hpp>
int main(int, char*[]) {
BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
BOOST_LOG_TRIVIAL(info) << "An informational severity message";
BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
BOOST_LOG_TRIVIAL(error) << "An error severity message";
BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
return 0;
}
One approach would be to pass a reference to a logger object around function calls. However, logging is a sort of an orthogonal aspect to application logic, so that explicitly passing that logger and having it as a member quickly becomes a nuisance and only adds artificial complexity.
I prefer having one global logger in the application. Modules can create its own loggers as child loggers of the main logger forming a hierarchy (I think this is similar to Python logging module) and control its output sink and verbosity independently if necessary.
I always use something like this:
class Log
{
public:
Log()
: m_filename( "dafault.log" )
{}
// if you wanna give other names eventually...
Log( const std::string & p_filename )
: m_filename( p_filename )
{}
virtual ~Log()
{
// implement your writeToFile() with std::ofstream
writeToFile( m_filename, m_stream, true );
}
template< typename T >
Log & operator<<( const T & p_value )
{
m_stream << p_value;
return *this;
}
private:
std::string m_filename;
std::ostringstream m_stream;
};
So this way I am able to log like this:
Log() << "My message in the log with numbers " << 1 << 2 << 3 << " and so on...";
Log( "other.log" ) << "Log in another file eventually...";
My current approach is to use a kind of dependency injection, using C++ strengths instead of magic. It does not require on anything specific to C++11 (except that __thread which is an extension could be replaced by thread_local if you wished to be Standard).
class LoggerEngine {
public:
static LoggerEngine* Current() { return CurrentE; }
virtual bool isActive(Level) { return true; }
virtual void log(char const* function,
char const* file,
int line,
std::string message) = 0;
// cuz' decorators rock
LoggerEngine* previous() const { return _previous; }
protected:
LoggerEngine(): _previous(CurrentE) { CurrentE = this; }
~LoggerEngine() { CurrentE = _previous; }
private:
static __thread LoggerEngine* CurrentE;
LoggerEngine* const _previous;
}; // class LoggerEngine
// in some .cpp file:
__thread LoggerEngine* LoggerEngine::CurrentE = 0;
And then, provide macros (to capture function, file and line):
#define LOG(L_, Message_) \
do { if (LoggerEngine* e = LoggerEngine::Current() and e->isActive(L_)) { \
std::ostringstream _28974986589657165; \
_28974986589657165 << Message_; \
e->log(__func__, __FILE__, __LINE__, _28974986589657165.str()); \
}} while(0);
However it could certainly be made better by using shims instead, because even though it prevents any computation in case the level is not active it still requires formatting of the full message (and the necessary memory allocation) even if it is going to truncate the message anyway (for example because it uses fixed-size buffers) and does not easily allow customization of the formatting.
The combination of stacking engines (and popping them off automatically using RAII) with thread-local behavior is really pretty neat. Most code only ever see an interface, without having to thread it by (cool when you have 4/5 different engines), and any level of the stack can switch the engine to something more appropriate.
There is one caveat, as is, no logging occurs before a first Engine is defined. For this reason I've often thought of defaulting to writing to the console if no engine is setup but... I've mostly changed my style to avoid computation before main is called since I cannot dependency-inject during this phase (and it's awkward if an exception fires...)
Usage is like this:
void benchmark() {
LOG(INFO, "Hello, World!");
Timer t;
{
MySinkLogger const _; (void)_; // a logger with "isActive" always false
for (size_t i = 0; i != 10000; ++i) {
LOG(INFO, "Flood!");
}
}
LOG(INFO, "Elapsed: " << t.elapsed());
}
int main() {
MyFileLoggerEngine const _("somefile.log"); (void)_; // a file logger
benchmark();
}
And normally this could create a file "somefile.log" containing:
2013-10-03T18:38:04.645512 mylaptop INFO <test.cpp#42> Hello, World!
2013-10-03T18:38:04.865765 mylaptop INFO <test.cpp#47> Elapsed: 0.220213s

Lazy logging in C++

Let's suppose that we have several levels of logging: trace, debug, info, error.
I was wondering if there is a way to write the following code:
enum log_level = {trace, debug, info, error};
log_level global_log_level = info;
void log(log_level level, string& message){
if (level >= global_log_level){
std::cout << message << std::endl;
}
}
string create_message(){
...
}
log_level level = debug;
log (level, create_message());
without create_message being called if level is smaller that global_severity_level. Indeed, create_message can be quite long, and no matter what it creates a string. If there are a lot of "debug" logs, those ones can become a substantial overhead when running in non-debug mode.
I know it is possible to do so if the function "log" is a macro, calling create_message() only if severity > minimal_severity; but isn't there another way to do this without macros?
EDIT
In the above, I didn't specify create_message, because it could be anything, in particular:
log(level, "Created object " + my_object.getName());
In this case, is there a way to write log such that the full string is not created, in a relatively transparent way for the programmer calling log?
Many thanks
Similar to #sftrabbit, but as suggested by #ipc.
Use a template to avoid the std::function machinery, and the compiler may be able to inline this and thus it hopefully will end up being faster.
template< typename F >
void log(log_level level, F message_creator){
if (level >= global_log_level){
std::cout << message_creator() << std::endl;
}
}
There are several alternatives. An interesting one is to pass create_message as a std::function<std::string()> and call it from within log:
void log(log_level level, std::function<std::string()> message_creator){
if (level >= global_log_level){
std::cout << message_creator() << std::endl;
}
}
Then you would call it like so:
log(level, create_message);
This can work with arbitrary expressions as arguments if you wrap them in a lambda:
log(level, [&](){ return "Created object " + my_object.getName(); });
If you really don't want to argument to be evaluated at all (as you've described in the comments), then you'll need to check the level outside of the call:
if (level >= global_log_level) {
log(level, create_message());
}
#sftrabbit answer is prefered. But just if you dont want to change log(), you can call it:
log (level, (level >= global_log_level)? create_message() : "");
You can create a macro
#define log(level, message) { \
if(level >= global_log_level) {\
cout &lt&lt message; }}
Now if you call log(debug, create_message()); create_message will be called only if debug level is the desired one.