ThrowTheSwitch / Ceedling

Ruby-based unit testing and build system for C projects

Home Page:http://throwtheswitch.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

gcov plugin "No executable lines" no longer skips file, but halts with exception

sammyj85 opened this issue · comments

With Debian 12, I found myself having to use Ceedling 0.32 release candidate (latest at time of writing). I made sure to upgrade the local instance of Ceedling inside the project also.

My existing project stopped working with a gcov error:

---------------------------
GCOV: CODE COVERAGE SUMMARY
---------------------------
...
isqrt.c Lines executed:100.00% of 13
isqrt.c Branches executed:100.00% of 4
isqrt.c Taken at least once:100.00% of 4
isqrt.c No calls
isqrt.c Lines executed:100.00% of 13

ERROR: Shell command failed.
> Shell executed command:
'gcov -n -p -b -o "build_test/gcov/out" "angle.c"'
> Produced output:
No executable lines
build_test/gcov/out/angle.gcno:cannot open notes file
build_test/gcov/out/angle.gcda:cannot open data file, assuming not executed
> And exited with status: [pid 7306 exit 1].

Exception raised in plugin: gcov, in method post_build
/data/vendor/ceedling/lib/ceedling/tool_executor.rb:84:in `exec': ShellExecutionException (ShellExecutionException)
        from /data/vendor/ceedling/plugins/gcov/lib/gcov.rb:89:in `block in report_per_file_coverage_results'
        from /data/vendor/ceedling/plugins/gcov/lib/gcov.rb:86:in `each'
        from /data/vendor/ceedling/plugins/gcov/lib/gcov.rb:86:in `report_per_file_coverage_results'
        from /data/vendor/ceedling/plugins/gcov/lib/gcov.rb:63:in `post_build'
        from /data/vendor/ceedling/lib/ceedling/plugin_manager.rb:99:in `block in execute_plugins'
        from /data/vendor/ceedling/lib/ceedling/plugin_manager.rb:97:in `each'
        from /data/vendor/ceedling/lib/ceedling/plugin_manager.rb:97:in `execute_plugins'
        from /data/vendor/ceedling/lib/ceedling/plugin_manager.rb:85:in `post_build'
        from vendor/ceedling/lib/../lib/ceedling/rakefile.rb:77:in `block in <top (required)>'
***** Unit Test FAILED *****

When run with the previous Ceedling version (or maybe it was the previous gcov version?), it did have the cannot open notes file and cannot open data file, assuming not executed notices, but then it skipped the file and moved on. It now raises an exception in the gcov plugin. Is there a way to revert to the skipping behaviour if there was no execution output? Perhaps this issue could be raised in the release notes with suggested fixes?

I have been attempting to exclude the file from gcov which has no execution lines, but I wasn't able to see any effect from the exclude parameters. The section of project.yml is below:

:gcov:
  :reports:
    - HtmlDetailed
  :utilities:
    - gcovr
  :gcovr:
    :html_medium_threshold: 75
    :html_high_threshold: 90
    :report_exclude: .*angle\.c

The gcov plugin parameters documentation:
https://github.com/ThrowTheSwitch/Ceedling/tree/master/plugins/gcov

gcovr filters documentation:
https://gcovr.com/en/stable/guide/filters.html

It sometimes complained about unescaped characters if I surrounded the regex in double quotes. None of the following attempts worked either.

:report_exclude: src\/driver\/angle\.c

:report_exclude: "src\/driver\/angle\.c"

:report_exclude: "^src\/driver\/angle\.c"

:report_exclude: "(.+/)?angle\.c$"

Also tried gcov_exclude with various regex forms with no luck.

:gcov_exclude: "src\/driver\/angle\.c"

Also tried file_filters, (but that seems to be for ReportGenerator, and I'm using gcovr), with no luck.

:file_filters: "-./vendor/*;-./build/*;-./test/*;-./lib/*;+./src/*;-./src/driver/angle.c"

Has anyone had any luck with excluding individual files?

# ceedling version
   Ceedling:: 0.32.0
      Unity:: 2.5.4
      CMock:: 2.5.4
 CException:: 1.3.3

# gcov --version
gcov (Debian 12.2.0-14) 12.2.0

# python3 --version
Python 3.11.2

According to my investigation, the root cause of this is that gcov has changed how it returns error codes: gcc-mirror/gcc@815f15d
This change happened between gcc-11 and gcc-12.

$ gcov-11 -n -p -b -w -o "test/build/gcov/out" "adc.c"
test/build/gcov/out/adc.gcno:cannot open notes file
test/build/gcov/out/adc.gcda:cannot open data file, assuming not executed
No executable lines
$ echo $?
0
$ gcov-12 -n -p -b -w -o "test/build/gcov/out" "adc.c"
test/build/gcov/out/adc.gcno:cannot open notes file
test/build/gcov/out/adc.gcda:cannot open data file, assuming not executed
No executable lines
$ echo $?
1

Our workaround is to not use the gcov plugin to run the test. Instead use the coverage flags on the normal test runner and then run the utils:gcov afterwards.
Our tests run like this now: ceedling clobber test:all utils:gcov instead of ceedling clobber gcov:all utils:gcov

We lose the file coverage report in the text output but we can live with that.

This is our flags part of project.yml:

:flags:
  :test:
    :compile:
      :*:
        - -fprofile-arcs
        - -ftest-coverage
        - -DGCOV_COMPILER
        - -DCODE_COVERAGE
        - -Werror
    :link:
      :*:
        - -fprofile-arcs
        - -ftest-coverage