10000 Exception when searching for headers in src and sources in .libs directory · Issue #508 · gcovr/gcovr · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Exception when searching for headers in src and sources in .libs directory #508

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 < 8000 a class="Link--inTextBlock" href="https://docs.github.com/terms" target="_blank">terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kcudnik opened this issue Aug 6, 2021 · 27 comments
Closed

Comments

@kcudnik
Copy link
kcudnik commented Aug 6, 2021

Describe the bug
when headers are in different directories then sources, i get this error:

header exception:

(gcovr could not infer a working directory that resolved it.)
Traceback (most recent call last):
  File "/usr/bin/gcovr", line 11, in <module>
    load_entry_point('gcovr==4.2', 'console_scripts', 'gcovr')()
  File "/usr/lib/python3/dist-packages/gcovr/__main__.py", line 253, in main
    print_reports(covdata, options, logger)
  File "/usr/lib/python3/dist-packages/gcovr/__main__.py", line 368, in print_reports
    generator(covdata, output.value, options)
  File "/usr/lib/python3/dist-packages/gcovr/html_generator.py", line 248, in print_html_report
    with io.open(data['FILENAME'], 'r', encoding=options.source_encoding,
FileNotFoundError: [Errno 2] No such file or directory: 'lib/src/Notification.h'

Notification.h is located in lib/inc/ not in lib/src

source exception:

        (gcovr could not infer a working directory that resolved it.)
Traceback (most recent call last):
  File "/usr/bin/gcovr", line 11, in <module>
    load_entry_point('gcovr==4.2', 'console_scripts', 'gcovr')()
  File "/usr/lib/python3/dist-packages/gcovr/__main__.py", line 253, in main
    print_reports(covdata, options, logger)
  File "/usr/lib/python3/dist-packages/gcovr/__main__.py", line 368, in print_reports
    generator(covdata, output.value, options)
  File "/usr/lib/python3/dist-packages/gcovr/html_generator.py", line 248, in print_html_report
    with io.open(data['FILENAME'], 'r', encoding=options.source_encoding,
FileNotFoundError: [Errno 2] No such file or directory: 'lib/src/.libs/SaiInterface.cpp'

SaiInterface.cpp is located in lib/src not lib/src/.libs/

To Reproduce
Steps to reproduce the behavior:

  1. clone sonic-swss-common (https://github.com/Azure/sonic-swss-common)
  2. compile with CXXFLAGS="" LDFLAGS="" ./configure --enable-code-coverage
  3. install swss-common deb package
  4. enable unix socket on redis server: vim /etc/redis/redis.conf anddng 2 lines:
  • unixsocket /var/run/redis/redis-server.sock
  • nixsocketperm 777
  1. cd /var/run/redis/
  2. ln -s redis-server.sock redis.sock
  3. clone sonic-sairedis (https://github.com/Azure/sonic-sairedis)
  4. update sumbodules: git submodule update --init --recursive
  5. compile with CXXFLAGS="" LDFLAGS="" ./configure --enable-code-coverage --with-sai=vs
  6. execute tests "make check" in root
  7. run gcovr -r ./ -e ".+/.libs/.+" --html --html-details --exclude-throw-branches --exclude-unreachable-branches -o htmlcov/index.html

I added exclude for /.libs/ since this is another bug, gcovr somehow search for cpp files in /.libs/ directory, not sure why, you can run without this exclude and you will get other error

Expected behavior
Everything should work fine

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Linux 5.11.0-25-generic 27~20.04.1-Ubuntu SMP Tue Jul 13 17:41:23 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
  • GCC gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
  • GCOVR gcovr 4.2
  • Project directory layout: (please find 2 repos in steps to reproduce)
    • Roots
    • Object directories

Additional context
Some files like SaiInterface.cpp are actually reused (compiled explicitly to different projects, you would need to check Makefile.am, I'm in process of refactoring sairedis library to reuse each file only once, and maybe this would help. Please reply to this issue if more data is needed. I'm currently working on code coverage for sairedis repo.

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

I am working on a smaller example that would be much easier to reproduce on your side, will notify when done

@Spacetown
Copy link
Member

Do you run gcovr in the same directory as the compiler?
Btw. your regex is wrong, the . of .libs should be masked.

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

I run gcov in root of repo directory, there are multiple directories in which compiler is runned.
Maybe regex is wrong but allowed to discover more errors :)

I prepared branch with minimal setup required, all commands to reproduce 3 errors:

$ mkdir tmp
$ cd tmp
$ git clone https://github.com/kcudnik/sonic-sairedis.git
$ cd sonic-sairedis/
$ git checkout gcovexample
$ ./check.sh

All test descriptions are in check.sh, should be very easy to recreate, all additional dependencies are stripped, o just keep most of original files, directory structures and Makefiles.am. I'm getting same error in this example as in original repo mentioned in issue topic.

Please try to recreate and if you need any more assistance, please ping me.

@Spacetown
Copy link
Member

Gcovr should be called from the same directory as the compiler to get the correct source paths.
Can you test the branch from #368 (comment)?
I've implemented a fallback to search a directory for the source files.

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

Sure, let me test that. Just a heads up, in this repo i have files cpp and h which have the same name, but they are in different directories and they expose content in different c++ namespaces, so from compiler point of view there is no conflict here. I will try to test given branch and will get back to you.

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

From this branch, i don't get exception but just some warnings:

(WARNING) File SAI/meta/.libs/saimetadata.c not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File SAI/meta/.libs/saimetadatautils.c not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File SAI/meta/.libs/saiserialize.c not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File lib/src/.libs/SaiInterface.cpp not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File meta/.libs/json.hpp not found: FileNotFoundError(2, 'No such file or directory')
(ERROR) Error occurred while printing reports

@Spacetown
Copy link
Member

This behavior was introduced with 5.0 (fc67f18) if the source file can't be found.

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

So this is interesting, report is still generated (but i'm not sure if it's full since error is printed) files appear in generated report with incorrect paths:
image
and after view it show not executed path but no file content:
image
so this don't solve the problem yet

@Spacetown
Copy link
Member

The problem is that GCC writes the file path relative to the working directory and gcovr tries to get the correct path. Can you run gcov from the same directory as the compiler and let gcovr collect the files?

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

Sure. So let's take a meta/ directory from the repo, if i call gcovr inside that directory, i don't get any errors, but only 4 files are visible on output:

Globals.cpp	 SaiAttributeList.cpp  sai_serialize.h	saiserialize.cpp	

other 3 files are still not visible which are in SAI/meta directory

                         $(top_srcdir)/SAI/meta/saimetadata.c \
                         $(top_srcdir)/SAI/meta/saimetadatautils.c \
                         $(top_srcdir)/SAI/meta/saiserialize.c

and corresponding *gcno files are also in that directory, but executing gcovr from SAI/meta gives those errors:

(WARNING) File .libs/saimetadata.c not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File .libs/saimetadatautils.c not found: FileNotFoundError(2, 'No such file or directory')
(WARNING) File .libs/saiserialize.c not found: FileNotFoundError(2, 'No such file or directory')

not sure why it searches those ins ".libs" directories, that's really strange

and there is also future question, im planning to add unit tests to this projects, and test will be located in another directory, but they will link with precompiled *.a files and execute from tests directories, so question here would be where the actual instrumentation data will be updated? This also exposes another question, since for example headers can have code itself, for example templates code, or explicit default constructor. So if header is used in 2 different directories, where would be his instrumental data included? And when gcovr should be run in this case?

@kcudnik
Copy link
Author
kcudnik commented Aug 6, 2021

@latk
Copy link
Member
latk commented Aug 7, 2021

Probably the same issue as in #386. Problem is probably a combination of the following factors.

  1. Gcovr doesn't know how to invoke gcov and just makes multiple guesses until one works.
  2. The gcov output includes relative file names. Gcovr uses heuristics to figure out the actual path of the source file. These heuristics are frequently wrong. Whole-project coverage is still accounted correctly, but it's potentially attributed to non-existent files.
  3. Even if the files actually exist, there might be an additional bug where the paths thus created are not accessed properly while creating the HTML report.

These problems naturally only manifest in more complex projects, so it is challenging to debug.

Since GCC 9 the gcov output actually includes a Working directory field which would sidestep problem # 2, but gcovr has yet to implement the necessary support.

@kcudnik
Copy link
Author
kcudnik commented Aug 7, 2021

Thank you for exhausting explanation and actually this project is compiled with g++ 9.3. I will have to figure out a way from smaller examples and probably manually shuffle gcov output files to specific directories. Just wanted to avoid that :)

@kcudnik
Copy link
Author
kcudnik commented Aug 10, 2021

I refactored in heavy way my repo, and currently commit "de9d484 (HEAD, origin/recursive_search_file" is not complaining any more and everything seems to work fine and be reported. I still find some couple issues:

  • for example this:
    image
    that is jus calling constructor and bind passes function as one of parameters, interesting how entire line executed, but bind line not :P should it be marked as executed when actual function from bind would be called?

  • and second this:
    image
    in both cases this and previous SWSS_LOG_ENTER() is just simple macro (across all project) that printf() current function name, there are no branches there, and in upper case 1/1 all passes and in bottom it shows 1/2, so some branches were not executed

im puzzled with those and can't figure out how those extra branches showed up there

@latk
Copy link
Member
latk commented Aug 12, 2021

@kcudnik Branch coverage on C++ code is a really tricky subject. Please refer to our FAQ entry Why does C++ code have so many uncovered branches?. Note that SWSS_LOG_ENTER() is not simply a printf, but creates an object with a destructor. Compilers sometimes generate multiple code paths for destructors, depending on whether the stack is being unwound for a return or for an exception. To actually understand what branches the compiler generates, it's not sufficient to look at the C++ source code but it would be necessary to look at the assembly code.

No idea about the missing line coverage for the one argument though. It is not always intuitive how the compiler associates code with lines if a statement stretches multiple lines. And by “not intuitive” I mean “I don't understand this either”.

So it's best to not read too much into these coverage metrics. They're great for directing your attention towards code that is under-tested, but 100% coverage is a rather problematic goal.

@kcudnik
Copy link
Author
kcudnik commented Aug 13, 2021

@latk Thanks for detail explanation, i already found that article which in detail explains this problem. Thank you for your input. Agree on coverage goals, but sometimes you have someone higher in the latter that have only % numbers in mind, not actually representing nothing. I can write C code with 3 different bugs which will cover 100% and will not have any branches :)

@Spacetown
Copy link
Member

@kcudnik Can this be closed?

@kcudnik
Copy link
Author
kcudnik commented Sep 16, 2021

is the proposed fix already on mater branch?

@Spacetown
Copy link
Member

Do you mean the Working directory of gcc-9?
I thought that it was solved by your reorganisation of the project folders.

@kcudnik
Copy link
Author
kcudnik commented Sep 19, 2021

I reduced 1 level of directories, but still get same issue, currently im using patch that was suggested but i would like to see fix on this repo too

@eseiler
Copy link
eseiler commented Oct 16, 2021

I'm not sure if this will help in this specific case, but there are quite a few issues in this repo where it might help. I had a bit of trouble getting gcovr to work with multiple build directories, and sources/header being in different directories.

What worked was passing -fprofile-abs-path to GCC (available with GCC>=8). This will cause gcov to report absolute paths instead of relative paths.

@Spacetown
Copy link
Member

@eseiler Can you check this with the branch of #597?

@eseiler
Copy link
eseiler commented Apr 3, 2022

@eseiler Can you check this with the branch of #597?

Sure, what do you need to check me exactly?

We are currently using gcovr 5.0 with gcc-11 and -fprofile-abs-path and it works flawlessly.
We use 5.0 because of #588

I can run our coverage builds with or without -fprofile-abs-path, depending on what you need :)

@Spacetown
Copy link
Member

Can you check the PR branch with and without -fprofile-abs-path? #588 is fixed on main branch and the PR should also fix problems when no abs paths are used bay gcovr.

@Spacetown
Copy link
Member

Is this issue still not solved with latest master branch?

@eseiler
Copy link
eseiler commented Feb 21, 2023

We are currently using 5.2 and it works again

@Spacetown
Copy link
Member

Closing because problem is solved.

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

No branches or pull requests

4 participants
0