linux-test-project / lcov

LCOV
GNU General Public License v2.0
866 stars 234 forks source link

line coverage looks strange, with cross compilation and remote collection #278

Closed Allen19930926 closed 3 months ago

Allen19930926 commented 3 months ago

Hi Henry, Sorry to bother you! However I have trouble in a strange problem. Due to the restriction to some 3rd party libraries, my project is built with a cross-compiler which is gcc 4.9(ARM) version, and runs on the arm-board. I collect the gcda data, and generate lcov report in the x86 PC with the gcc 4.8(X86). It's strange that the line counts of the code is not right when the line has a wrap. I have no idea to confirm that this problem is caused by gcov or lcov. Please give me some suggestions to confirm it. Thanks a lot.

lcov 2.0 - 1 gcov(cross-compiler) gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabi gcov(x86, generate report) gcc 4.8.4 default version in ubuntu14.04

Please have a look at line 117-119, the function "memcpy" is distributed in multiple lines. Actually, we suppose the 3 lines would be coverd when the "memcpy" function hitted. However, it only coverd one line, while the others could not be coverd anymore.

Snipaste_2024-03-28_17-45-59

henry2cox commented 3 months ago

No worries :-) Isn't cross-compilation and remote data collection fun...

I guess you have verified that you are using the same source code version on the board as on the host (we have seen such issues in the past). I seriously doubt that that is your problem, though - both because I bet that you already checked, and because all the other lines seem nicely aligned.

The issue is almost certainly gcov - or really, the compiler instrumentation that gcov is looking at. There are a couple of things you can do to confirm, and one possible workaround you can try. To verify:

Possible workaround:

If this was really important to you and you had time to commit to it, the other thing you could do is to make lcov smarter about what is and is not a line of C code - and then filter out the two bogus lines (117 and 118) and move the data from 119 to 117. Such a filter would be quite useful - especially in nontrivial C++ code - but would be difficult to get right/hard to verify. (Completely changing how lcov currently does filtering would be your best bet, I think...current approach is too much of a hack and too limited.)

The other way out is to add exclusion markers at the offending code. Should not have been necessary...but real life sometimes gets in the way of perfection. Some tools have a 'signed off' marker for such cases...but lcov doesn't (yet).

Allen19930926 commented 3 months ago

Hi Henry, sorry to late response! Here is the results that you advised me to verify.

verify results turn up verbositly (-v -v) , while I think it helps little. The log does not contain any log on line 117-119 image

save the intermediate gcov files, I don't know how to parse it, so I open the file in vim. Here is the snapshot. image

more, line hit of the file is below: image

possible solutions

I would like to to solve the problem rather than avoiding it. This will leave a reference solution for others. Again thanks very much for your suggestion!!

henry2cox commented 3 months ago

WRT using temporaries (which may or may not help): the issue isn't putting the function call on one line (though, now that you mention it: it should have the desired effect). Instead, the issue is the expression evaluation that the compiler needs to do for each parameter (though, since this appears to be vanilla C code, that should be just an address calculation and load). If each of those expression evaluations have their own source lines, the coverage data is not as likely to be confused. (This tends to work fairly well with C++ code, when you are trying to eliminate phantom branches associated with exception handlers, for example. For straight C...not sure we have noticed a need. YMMV.)

Sorry for lack of clarity...the intent of the "turn up verbosity" suggestion was so that you could see the gcov command line that is forked - so you could rerun that command in locally and look at the output. Same idea as --preserve - which was to leave the shrapnel in place so you could look at it.
Looks like you found it, though...and yes. We see zero hit counts on those lines.

GCC/4.9 is pretty old. You probably don't have the option on your embedded platform - but upgrading to a newer compiler may also solve your problem (or may not).

For this particular issue: I don't think that using a newer lcov version (say, cloned top-of-tree rather than the 2.0 package) would make any difference. For your other issue: it might. (There have been a lot of bug fixes.)

Allen19930926 commented 3 months ago

Thanks for your effort, Henry! This issue could be closed.

The problem seems to be gcov's issue and lcov could do little about it since lcov is an application of gcno and gcov data.

I will change the clang-format parameter to allow more characters in one line to avoid this problem and also decide to do some efforts to transplant the project to x86 platform that eliminates a lot of problems.

I will try the latest lcov for another issue soon. https://github.com/linux-test-project/lcov/issues/279

henry2cox commented 3 months ago

My preference/general policy is to hope that the person who opened the issue will close it, when/if they think it is complete. (I violate that policy for lingering reports where the user seems to have vanished.)