Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

Different code coverage results on Windows and Linux

Maarten_Menken
Beginner
648 Views
Hello,

When I use the Intel code coverage tool on Linux, I get results that I cannot explain. Following is a short test program to illustrate my issues.

[cpp]// File: main.cpp
#include 
#include 

struct foo
{
   foo();
   ~foo();
};

foo::foo() {}

foo::~foo() {}

int main()
{
   foo f;

   std::string s1 = "hello, ";
   std::string s2 = "world";
   std::cout << s1 + s2 << std::endl;

   return 0;
}[/cpp]

I run the following commands to build/execute/post-process:

[shell]icpc -g -O0 -prof-genx -c main.cpp -o main.o # Intel C++ Compiler 10.1, or
icpc -g -O0 -prof-gen=srcpos -c main.cpp -o main.o # Intel C++ Compiler 11.0
icpc main.o -o main
./main
profmerge
codecov -nopartial[/shell]

On Windows, using Intel C++ Compiler 10.1.022, all functions and blocks are covered. This is what I would expect.

On Linux, using Intel C++ Compiler 10.1.018, or 11.0.083, the function coverage drops to 71,43% and the block coverage to 69,77%. This is not the overall coverage, just the coverage of main.cpp. The "foo::" parts of both the constructor and destructor are colored red in the HTML-output (indicating uncovered functions). However, both this constructor and destructor are listed among the covered functions, and there is no list of uncovered functions in the HTML-output for file main.cpp. The "+ s2" part in the phrase "s1 + s2" is colored yellow, indicating partial coverage. I do not understand this because the code does not contain any conditional statements.

Moreover, when I comment out both the declaration and implementation of foo's destructor, I get even different coverage of the std::string-related source code lines in main(). foo's destructor should have no effect on the coverage of those lines.

Could someone please help me understand this behavior? Thanks in advance,

Maarten Menken
0 Kudos
4 Replies
Dale_S_Intel
Employee
648 Views
Quoting - mrmenken

Could someone please help me understand this behavior? Thanks in advance,

Maarten Menken

Well, I'm still looking into it but it appears to be that there are some extra blocks and functions that the compiler puts in that are not normally hit. I think this might be related to the way it does exception handling on Linux vs. Windows. The lower function coverage seems to come from some alternate versions of constructors and destructors that are produced on Linux and not on windows. I'll let you know if I figure out more details about it, but it looks like the coverage tool is trying to do the right thing, it's just getting a little confused by some of the complexities of what the compiler puts out to handle some C++ features.

Dale

0 Kudos
Maarten_Menken
Beginner
648 Views

Well, I'm still looking into it but it appears to be that there are some extra blocks and functions that the compiler puts in that are not normally hit. I think this might be related to the way it does exception handling on Linux vs. Windows. The lower function coverage seems to come from some alternate versions of constructors and destructors that are produced on Linux and not on windows. I'll let you know if I figure out more details about it, but it looks like the coverage tool is trying to do the right thing, it's just getting a little confused by some of the complexities of what the compiler puts out to handle some C++ features.

Dale


Thanks for your quick reply.

One of the conclusions I draw from this is that it is virtually impossible to get a 100% coverage on Linux, because there will be generated functions and blocks over which I have seemingly no control. I would have hoped that the "-nopartial" option also compensates for these.

It may not be fair or right to compare the results with Gcov (the GCC test coverage program), but with Gcov I get a 100% coverage.
0 Kudos
Dale_S_Intel
Employee
648 Views
Quoting - mrmenken

Thanks for your quick reply.

One of the conclusions I draw from this is that it is virtually impossible to get a 100% coverage on Linux, because there will be generated functions and blocks over which I have seemingly no control. I would have hoped that the "-nopartial" option also compensates for these.

It may not be fair or right to compare the results with Gcov (the GCC test coverage program), but with Gcov I get a 100% coverage.

I'm afraid I can't comment intelligently on Gcov, not having tried it myself (I leave it as an exercise for the reader to determine if I can comment intelligently on anything else :-). I can explain a bit more about what's going on on our end. The problem with function coverage being less than 100% appears to be related to the fact that the ABI requires 2 different constructors, which is not the case on Windows. Only one of those constructors is used in this case so the code coverage tool sees some constructors not being executed. I think the reason that the block coverage is sparse may be related to some extra blocks inserted by the compiler to support exception handling, which do not get executed in the typical case (or something like that).

There are some extra knobs to turn in the code coverage tool to filter out certain patterns of function names, I can look into that a bit and see if there's something easy that could be done for that. For the basic block coverage I suspect there may not be much to be done by the user. It would be a little tricky even for the coverage tool to determine if there are some blocks that can be filtered out, but I can talk to people who know more than me about this stuff and see if there are any feasible possible solutions at some point in the future.

So, in short, you may be right about not being able to do much about the block coverage, but we might be able to figure out how to filter out functions that don't matter.

Dale

0 Kudos
Maarten_Menken
Beginner
648 Views

There are some extra knobs to turn in the code coverage tool to filter out certain patterns of function names, I can look into that a bit and see if there's something easy that could be done for that. For the basic block coverage I suspect there may not be much to be done by the user. It would be a little tricky even for the coverage tool to determine if there are some blocks that can be filtered out, but I can talk to people who know more than me about this stuff and see if there are any feasible possible solutions at some point in the future.

Thanks again Dale. From the documentation I gather that it is only possible to filter out functions that have been marked with a particular comment (e.g. by adding "// INFEASIBLE" at the beginning of the function implementation). Not sure if this can be applied to the "hidden" generated functions. Please let me know if you find out more.
0 Kudos
Reply