C++ macro to log every line of code - c++

During one of my recent discussions with my manager, he mentioned that one of his former clients used a C++ macro to log info about every line of code. All they had to do was enable an environment variable before starting the run. (Of course the environment variable was enabled in the test-bed alone.
The log mentioned the variables used and their corresponding values too.
For example, for the line:
a = a + b;
The log would say something like:
"a = a + b; (a = 5 + 3)"
Personally, I was not sure if this was possible, but he was very sure of this having existed, though he did not remember the specifics of the code.
So, here is the (obvious) question: Is this possible? Can you provide the code for this one?

I don't know if every line/variable can be expanded like that, but function calls can be logged. I have logged all function calls using the -finstrument-functions option of gcc. It will call:
void __cyg_profile_func_enter (void *this_fn, void *call_site);
and
void __cyg_profile_func_exit (void *this_fn, void *call_site);
for function enter and exit.
The docs explain how to use it. I don't know if other compilers offer something similar.

You may check how BOOST_CHECKA from Boost.Test is implemented. Internally it uses expression templates.
For test:
#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>
#include <boost/test/test_tools.hpp>
BOOST_AUTO_TEST_CASE(test1)
{
int a=0;
int b=1;
int c=2;
BOOST_CHECKA( a+b == c );
}
Output is:
Running 1 test case...
main.cpp(11): error: in "test1": check a+b == c failed [0+1!=2]
*** 1 failure detected in test suite "Master Test Suite"
Note values in square brackets: [0+1!=2]
It has some limitations.
For test:
BOOST_CHECKA( (a+b) == c );
output is:
check (a+b) == c failed [1!=2]

Related

Replace C++ class/static method with preprocessor?

I'd like to use the built-in compiler checks to verify format strings of a custom logging framework to catch the odd runtime crash due to mismatching format string <-> parameters in advance.
Arguments of the custom C++ logging methods are identical to the printf() family so I was attempting to replace all calls to
MyLogger::Error(
with
fprintf(stderr,
Though unfortunately the (clang) preprocessor chokes on the scope resolution operator (::), i.e. instead of ULog::Warn( only the ULog substring is recognized:
#define MyLogger::Error( fprintf(stderr,
Any suggestions on how to make this work much appreciated.
Have you tried a variadic template? found here.
#include <iostream>
namespace MyLogger
{
template <typename... T>
auto Error(const char * _Format, T &&... args)
{
return printf(_Format, std::forward<T>(args)...);
};
}
#define printf(...) MyLogger::Error(__VA_ARGS__)
int main()
{
MyLogger::Error("Non-Macro Print \n");
printf("Macro Print \n");
return 0;
}
Elaborating on the approach suggested by #Someprogrammerdude I've extended the custom logging class to use the clang/gcc format attribute to enable compiler format checking.
The declaration simply becomes
static void Error(const char *format,...) __attribute__ ((format (printf, 1, 2)));
It's even better than the original idea to use the preprocessor to temp. enable checks by replacing calls to the custom formatter with calls to printf() as it's enabled all the time catching argument mismatches immediately!
(FWIW - already fixed dozens of issues and couple potential crashes on our 120+ LOC code base)
What if you modify MyLogger::Error to
MyLogger::Error(args){
if (0) {
fprintf(stderr,args)
}
//actual function
}
This way you get the built-in warnings and it does not effect the efficiency of your code. (You can obviosly actually use the print if you wan to write to stderr, but I think if you wanted that you used that already)

silence warnings about unused variables/functions at the point of their conditionally compiled usage

So in doctest (my testing framework) the user can disable all tests by defining the DOCTEST_CONFIG_DISABLE identifier which makes the following code and macros:
TEST_CASE("name") {
int a = 5;
int b = 6;
CHECK(a == b);
}
turn into the following after the preprocessor:
template<typename T>
void some_anon_func_123() {
int a = 5;
int b = 6;
}
that means that the self-registering test case is turned into an uninstantiated template function and the CHECK() macro (which functions as an if statement checking the condition) into a no-op - like this:
#define CHECK(x) ((void)0) // if disabled
However if the user has factored such testing code in a separate function like this:
static int g() {
std::cout << "called!" << std::endl;
return 42;
}
static void f() {
int a = 5;
CHECK(a == g());
}
TEST_CASE("name") {
f();
}
then there will be warnings for unused functions and unused variables. doctest prides itself with producing 0 warnings even on the most aggressive levels so this is unacceptable.
I tried using the ((void) ...) trick by passing it the macro argument like this:
#define CHECK(x) ((void)(x))
and that indeed silenced the warnings (atleast for a and g()) but there is still code being generated for that statement - if I invoke the f() function from my main() I will see the called! string printed in the console. This is undesirable since I want the compilation to be as fast as possible when test cases and asserts are disabled from the build (by using the DOCTEST_CONFIG_DISABLE identifier). If a user has 100 000 asserts and builds with them disabled he wouldn't want all that unnecessary codegen and compile time overhead for macros that are supposed to be disabled (the CHECK() one).
__attribute__((unused)) has to be used at the point of declaration of a variable - I cannot stick it in the CHECK() macro (or can I? I don't know...).
Not sure if _Pragma() could help - and even if it could - it is known to have issues with GCC:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
Is there a solution to my problem - like perhaps passing the expression to some template or whatever...? (C++98 solution needed)
I explained my problem in excruciating detail only because I often get accused of the XY problem...
EDIT:
A C++11 solution is OK too - some C++11 features have started to conditionally creep into the library anyway...
So, you want to "lie" to the compiler that you're using a function which you're not actually calling. So how to use a piece of code without executing it?
It seems that the only thing that works on all popular compilers is a C++11-only solution - a lambda which is never called:
#define CHECK(x) [&](){ ((void)(x)); }
If you absolutely need a c++98 solution, a sizeof will also work on many compilers, MSVC being a notable exception:
#define CHECK(x) sizeof(x)
MSVC will still warn for uncalled functions in the expression x.
I guess for maximum coverage you could employ a combination of the two.

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

how to get error line number in C++ program

I want to handle errors in my c++ program, so I created some exception classes to manage those errors, but I want to specify at which line in my program the error occurred.
I passed LINE macro to the constructor of my exception class.
For example:
void f(int i){ // LINE A
if(i<0)
throw(OutOfRange("message", __LINE__); // LINE B
}
void main(){
try{
f(-6); // LINE C
}
catch(const OutOfRange& error){
//do something
}
}
In this example I can only get the LINE B number, but I want to get LINE A and LINE C numbers.
Any idea, where and how to use LINE macro ??
Thanks.
You are looking for a stack trace and there's no portable way to get it. Something somewhat similar can be achieved with:
struct SourcePoint
{
const char *filename;
int line;
SourcePoint(const char *filename, int line)
: filename(filename), line(line)
{ }
};
std::vector<SourcePoint> callstack;
struct SourcePointMarker
{
SourcePointMarker(const char *filename, int line)
{
callstack.push_back(SourcePoint(filename, line);
}
~SourcePointMarker()
{
callstack.pop_back();
}
}
#define MARK_FUNCTION \
SourcePointMarker sourcepointmarker(__FILE__, __LINE__);
Then right after the beginning of each function (or point of interest) you just add a line... for example
int myFunction(int x)
{
MARK_FUNCTION
...
}
Using this approach in your error handlers you can know who was called by who and so on (of course you will know only functions or places that have been instrumented with MARK_FUNCTION). If this is needed only during testing (and not in production) then probably you should just enable core dumps and learn how to run a debugger in post-mortem analysis.
You need a stack trace and a debugger. There's no way in Standard C++ that you could find line C without passing it in as an argument (f(-6, __LINE__)), and no way at all that you could find Line A.
Line C would be near impossible (I can't think of a way... except by passing a second argument to f, __LINE__.
Line A as follows:
void f(int i){ const int lineA = __LINE__;
if(i<0)
throw(OutOfRange("message", __LINE__); // LINE B
}
The CPPUNit framework uses macros instead of functions. That way you can easily get the line number at the same place where the macro is called.
I don't think it is a valid approach in a general sense, but you may find it interesting to take a look at the way the CPPUnit developers did it.
In addition to __LINE__, you can also use __func__ and __FILE__ to give you more information.
__func__ will give you line A and you can at least get a line inside the catch-block by rethrowing from there, but I don't know another way to get line C.
It would probably help you to create a backtrace using standard C++11, i.e. cross-platform and without the need for a debugger or cumbersome logging.
In the years since this question was asked, some useful features have been added to C++.
You can trace the call stack that led to an exception using:
std::nested_exception and std::throw_with_nested
It is described on StackOverflow here and here
This will, however, require that you insert try/catch statements at the functions you wish to trace (i.e. functions without this will not appear in your trace).
You could automate this with macros, reducing the amount of code you have to write/change.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"

Code coverage (c++ code execution path)

Let's say I have this code:
int function(bool b)
{
// execution path 1
int ret = 0;
if(b)
{
// execution path 2
ret = 55;
}
else
{
// execution path 3
ret = 120;
}
return ret;
}
I need some sort of a mechanism to make sure that the code has gone in any possible path, i.e execution paths 1, 2 & 3 in the code above.
I thought about having a global function, vector and a macro.
This macro would simply call that function, passing as parameters the source file name and the line of code, and that function would mark that as "checked", by inserting to the vector the info that the macro passed.
The problem is that I will not see anything about paths that did not "check".
Any idea how do I do this? How to "register" a line of code at compile-time, so in run-time I can see that it didn't "check" yet?
I hope I'm clear.
Usually coverage utilities (such as gcov) are supplied with compiler. However please note that they will usually give you only C0 coverage. I.e.
C0 - every line is executed at least once. Please note that a ? b : c is marked as executed even if only one branch have been used.
C1 - every branch is executed at least once.
C2 - every path is executed at least once
So even if your tests shows 100% C0 coverage you may not catch every path in code - and probably you don't have time to do it (number of paths grows exponentially with respect to branches). However it is good to know if you have 10% C2 or 70% C2 (or 0.1% C2).
Quite often there will be a utility supplied with your compiler to do this sort of code coverage analysis. For example, GCC has the gcov utility.
You need a code coverage program (gcov, bullseye, dev partner) and unit-testing (unittest++, cppunit, etc.). You write test that will test that function.
TEST( UnitTestFunction )
{
CHECK( function(true) == 55 );
CHECK( function(false) == 120 );
}
Then unit tests in this case do not just check for integrity (though they still do) but they also test for coverage.
Try SD C++ TestCoverage for a VisualStudio compatible test coverage tool. I believe that it in fact actually will tell you about test coverage of a?b:c, too.
The problem is that I will not see anything about paths that did not "check".
If this means in other words that you're not only looking for the set of code points which are actually executed but also for the set of code points which have been "marked" somehow as expected to be executed to maybe finally report the difference, i might have a very dangerous solution. It works for me on MSVC 2010 and 2013.
The approach is to make use of the pre program start initialization of static variables, but since all code points are in functions and therefore, the "static anker point" has to be put there somehow and so, the c++ feature of delayed initialization of static function variables has to be overcome.
This seems to be possible by adding an indirection through a template class (X) with a static member variable (progloc_) to enforce the initialization per template parameter which in turn is a wrapper struct which transports the needed information (_.FILE._ " at line " _.LINE._).
Putting this together, the most important code to achieve this could look like the following:
template <class T> class X {
public:
static T progloc_;
};
template <class T> T X<T>::progloc_;
#define TRACE_CODE_POINT \
struct ProgLocation { \
public: \
std::string loc_; \
ProgLocation() : loc_(std::string(__FILE__ " at line " S__LINE__)) \
{ \
TestFw::CodePoints::Test::imHere(loc_); \
} \
}; \
TestFw::CodePoints::X<ProgLocation> dummy; \
TestFw::CodePoints::Test::iGotCalled(dummy.progloc_.loc_);
The S__LINE__ - trick which is used in the ProgLocation - ctor comes from here on SO.
#define S(x) #x
#define S_(x) S(x)
#define S__LINE__ S_(__LINE__)
To track, the following is used:
class Test
{
private:
typedef std::set<std::string> TFuncs;
static TFuncs registeredFunctions;
static TFuncs calledFunctions;
public:
static int imHere(const std::string fileAndLine)
{
assert(registeredFunctions.find(fileAndLine) == registeredFunctions.end());
registeredFunctions.insert(fileAndLine);
return 0;
}
static void iGotCalled(const std::string fileAndLine)
{
if (calledFunctions.find(fileAndLine) == calledFunctions.end())
calledFunctions.insert(fileAndLine);
}
static void report()
{
for (TFuncs::const_iterator rfIt = registeredFunctions.begin(); rfIt != registeredFunctions.end(); ++rfIt)
if (calledFunctions.find(*rfIt) == calledFunctions.end())
std::cout << (*rfIt) << " didn't get called" << std::endl;
}
};
Maybe there are many problems connected with this approach which I don't see yet and make it inpracticable for your case, and as others pointed out, using static code analysis tools is for most situations the better solution.
EDIT:
Just found out that the provided solution has been discussed before in another context:
non-deferred-static-member-initialization-for-templates-in-gcc
You can use FILE and LINE preprocessor directives:
#define TRACE(msg) MyTraceNotify(msg,__FILE__,__LINE__)
Just insert TRACE(msg) macro in your code at the places you want to track, with your custom message, and write your MyTraceNotify function.
void MyTraceNotify(const char *msg, const char *filename, ULONG line)
{
/* Put your code here... */
}