Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow lcov exclusion markers inside macros #44

Open
pwithnall opened this issue Oct 5, 2018 · 8 comments
Open

Allow lcov exclusion markers inside macros #44

pwithnall opened this issue Oct 5, 2018 · 8 comments

Comments

@pwithnall
Copy link

In GLib, there are a couple of macros which are used to implement preconditions on user functions, called g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached(), etc. These expand out to an ‘if’ statement with one branch which is expected to always be taken, and the other branch which is expected to never be taken, and which shouldn’t be tested for in test cases because testing the preconditions for every user function would be a waste of time.

It would be nice if lcov supported using LCOV_EXCL_* inside the macro definitions so that the second branch was ignored in every instance of the macros without having to annotate them all separately.

(This was originally reported as https://sourceforge.net/p/ltp/feature-requests/8/.)

@latk
Copy link

latk commented Oct 5, 2018

I don't think this is possible. Not only would lcov have to expand those macros in order to understand whether a line/branch should be excluded, comments are also removed by the preprocessor. So there's no way to put this info into a macro.

The better alternative might be to configure the exclusion markers to also match these macro names. The lcovrc man page suggests something like this should work:

lcov_excl_br_line = LCOV_EXCL_BR_LINE|g_return_if_fail|g_return_val_if_fail

(and so on for all the macro names)

@pwithnall
Copy link
Author

I’ll give that a go, thanks. The downside of that is that every project which uses those macros from GLib (which is a lot of projects) will have to learn about and copy the same lcovrc configuration when they do code coverage, which seems highly redundant. I don’t think any project would ever reasonably want to have coverage of the branches in those macros — they’re essentially equivalent to assert().

gnomesysadmins pushed a commit to GNOME/glib that referenced this issue Oct 6, 2018
While we can’t add markers to the macro implementations to cause lcov to
ignore them automatically, we can change our lcov configuration to
ignore all calls to them.

See linux-test-project/lcov#44.

This causes all the un-takeable branches and un-reachable assertions to
be ignored by our code coverage, which bumps our statistics:
 • Lines: 74.9% → 74.8%
 • Functions: 82.3% → 82.3%
 • Branches: 53.3% → 64.2%

The rationale is that nobody should be testing programmer error
handling, as g_return_*if_fail() are used to guard against — so it’s not
reasonable to count missed branches like that in code coverage
statistics.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
@mosra
Copy link

mosra commented Nov 23, 2018

What about using the _Pragma() C99 / C++11 preprocessor command for this? For example, lcov could support detectings things like

#pragma LCOV EXCL_START

in addition to comments. Unlike with comments, the preprocessor preserves these in the output (but yes, it would still need to look into the preprocessor output for these, which I'm not sure it is doing already). The macro could then look like this:

#define g_return_if_fail(expr) \
    _Pragma("LCOV EXCL_START") \
    do { if(!(expr)) ... } while(0) \
    _Pragma("LCOV EXCL_STOP")

Of course, this will make GCC complain on -Wall, so with the warning suppressed it becomes a bit hairy:

#define g_return_if_fail(expr) \
    _Pragma("GCC diagnostic push") \ 
    _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") \
    _Pragma("LCOV EXCL_START") \
    do { if(!(expr)) ... } while(0) \
    _Pragma("LCOV EXCL_STOP") \
    _Pragma("GCC diagnostic pop")

Opinions? :)

@oberpar
Copy link
Contributor

oberpar commented Mar 1, 2019

LCOV does not look at preprocessed code output, only at the original source code files associated with each coverage data file (.gcda). I don't see a feasible way to implement this feature in LCOV.

Maybe this could be added to GCC? Adding @marxin to the discussion: Is the ability to mark code as to be excluded from code coverage measurements something that could be implemented in GCC?

@marxin
Copy link

marxin commented Mar 4, 2019

Maybe this could be added to GCC? Adding @marxin to the discussion: Is the ability to mark code as to be excluded from code coverage measurements something that could be implemented in GCC?

One can use no_instrument_function function attribute for the else branch in a macro. That should skip instrumentation. That's what I can offer.

@feliwir
Copy link

feliwir commented Oct 31, 2019

Any progress on this issue?

@B-HWD
Copy link

B-HWD commented Apr 13, 2021

Still no progress?

@henry2cox
Copy link
Collaborator

Just noticing/revisiting this issue.

I believe that @latk 's comment above is the best approach given that neither gcc nor llvm are likely to make the required enhancements to support the feature, and that lcov/geninfo/genhtml are rather simple tools and are not likely to become full-fledged compilers.

@pwithnall is also correct: all projects that want to use this feature will have to learn about it :-(
If this is a serious problem - then we could either add the required exclusion regexps to the lcovrc shipped with lcov releases (either in a commented out section or as is) - or a (brief) discussion of this issue could be added to the man page.

Now that we allow multiple RC files (see the --config-file option in the man page): we could add all of these typical/recommended exclusions to another RC file that we also include with the release - and add a corresponding discussion to the man pages.

What do people think?

Henry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants