GCOV Coverage analysis for C/C++ code on Linux

Must-share information (formatted with Markdown):

  • which versions are you using: SonarQube Developer Edition - Version 7.9 (build 26994)
  • what are you trying to achieve: I am trying to get the code coverage working using sonar.cfamily.gcov.reportsPath
  • what have you tried so far to achieve this: Read below

Try to clone https://github.com/peter-toft-greve/democode_sonarqube on a normal Linux machine - where gcov is installed.
With “make” I make code coverage analysis into “demo.gcov” like this


                       GCC Code Coverage Report

Directory: .

File Lines Exec Cover Missing

ext_fct.c 5 4 80% 6
main.c 5 4 80% 8

TOTAL 10 8 80%

I would hope/expect that adding
-Dsonar.cfamily.gcov.reportsPath=.
to the sonar-scanner command (cf. https://docs.sonarqube.org/latest/analysis/coverage/)
I could have SonarQube show the coverage integrated into the web.
At the moment I have zero coverage and with the sonar.cfamily.gcov.reportsPath activated I have the sonar-scanner failing with

09:30:30 java.lang.NullPointerException 09:30:30 at org.sonar.api.batch.fs.internal.DefaultFilePredicates.is(DefaultFilePredicates.java:135) 09:30:30 at com.sonar.cpp.plugin.gcov.GcovSensor.lambda$execute$2(GcovSensor.java:56) 09:30:30 at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) 09:30:30 at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source) 09:30:30 at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source) 09:30:30 at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source) 09:30:30 at java.base/java.util.Iterator.forEachRemaining(Unknown Source) 09:30:30 at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source) 09:30:30 at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) 09:30:30 at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) 09:30:30 at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) 09:30:30 at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) 09:30:30 at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) 09:30:30 at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) 09:30:30 at com.sonar.cpp.plugin.gcov.GcovSensor.scan(GcovSensor.java:75) 09:30:30 at com.sonar.cpp.plugin.gcov.GcovSensor.execute(GcovSensor.java:52) 09:30:30 at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48) 09:30:30 at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85) 09:30:30 at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59) 09:30:30 at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77) 09:30:30 at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59) 09:30:30 at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82) 09:30:30 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 09:30:30 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 09:30:30 at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:400) 09:30:30 at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:395) 09:30:30 at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:358) 09:30:30 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 09:30:30 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 09:30:30 at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:141) 09:30:30 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 09:30:30 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 09:30:30 at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73) 09:30:30 at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67) 09:30:30 at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46) 09:30:30 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 09:30:30 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 09:30:30 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 09:30:30 at java.base/java.lang.reflect.Method.invoke(Unknown Source) 09:30:30 at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60) 09:30:30 at com.sun.proxy.$Proxy0.execute(Unknown Source) 09:30:30 at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185) 09:30:30 at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137) 09:30:30 at org.sonarsource.scanner.cli.Main.execute(Main.java:112) 09:30:30 at org.sonarsource.scanner.cli.Main.execute(Main.java:75) 09:30:30 at org.sonarsource.scanner.cli.Main.main(Main.java:61)

I don’t get much info from a similar report - but see that it should be possible

make can generate demo.gcov
and sonarqube.sh can integrate to SonarQube - but I presumabe that the Makefile line 4 is not generating the format that SonarQube expects. More options needed??

Hi @peter.toft,

could you please share the entire sonar-scanner log?

$ ./sonarqube.sh
rm -f demo *.gcov *.gc*
--2019-08-14 14:04:30--  http://localhost:8082/sonarqube/static/cpp/build-wrapper-linux-x86.zip
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:8082... connected.
HTTP request sent, awaiting response... 200 
Length: unspecified [application/zip]
Saving to: ‘build-wrapper-linux-x86.zip’

     0K .......... .......... .......... .......... ..........  148M
    50K .......... .......... .......... .......... ..........  182M
   100K .......... .......... .......... .......... ..........  230M
   150K .......... .......... .......... .......... ..........  222M
   200K .......... .......... .......... .......... ..........  216M
   250K .......... .......... .......... .......... ..........  147M
   300K .......... .......... .......... .......... ......      116M=0.002s

2019-08-14 14:04:30 (171 MB/s) - ‘build-wrapper-linux-x86.zip’ saved [354997]

Archive:  build-wrapper-linux-x86.zip
   creating: build-wrapper-linux-x86/
  inflating: build-wrapper-linux-x86/build-wrapper-linux-x86-64  
  inflating: build-wrapper-linux-x86/libinterceptor-i686.so  
  inflating: build-wrapper-linux-x86/libinterceptor-x86_64.so  
rm -f demo *.gcov *.gc*
gcc -o demo main.c ext_fct.c -g --coverage -fprofile-arcs -ftest-coverage
./demo
I am not so negative any more
gcovr -o demo -o demo.gcov
INFO: Scanner configuration file: /usr/local/src/sonar-scanner-4.0.0.1744-linux/conf/sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: SonarQube Scanner 4.0.0.1744
INFO: Java 11.0.3 AdoptOpenJDK (64-bit)
INFO: Linux 4.15.0-1043-aws amd64
INFO: User cache: /var/lib/jenkins/.sonar/cache
INFO: SonarQube server 7.9.0
INFO: Default locale: "en", source code encoding: "UTF-8" (analysis is platform dependent)
INFO: Load global settings
INFO: Load global settings (done) | time=106ms
INFO: Server id: BF41A1F2-AWvA4nUDPMYzph8vLIYs
INFO: User cache: /var/lib/jenkins/.sonar/cache
INFO: Load/download plugins
INFO: Load plugins index
INFO: Load plugins index (done) | time=43ms
INFO: Load/download plugins (done) | time=164ms
INFO: Loaded core extensions: developer-scanner
INFO: Process project properties
INFO: Execute project builders
INFO: Execute project builders (done) | time=4ms
INFO: Project key: democode
INFO: Base dir: /var/lib/jenkins/workspace/ddsp_democode
INFO: Working dir: /var/lib/jenkins/workspace/ddsp_democode/.scannerwork
INFO: Load project settings for component key: 'democode'
INFO: Load project settings for component key: 'democode' (done) | time=96ms
INFO: Load project branches
INFO: Load project branches (done) | time=14ms
INFO: Load project pull requests
INFO: Load project pull requests (done) | time=9ms
INFO: Load branch configuration
INFO: Load branch configuration (done) | time=1ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=100ms
INFO: Detected Jenkins
INFO: Load active rules
INFO: Load active rules (done) | time=4938ms
INFO: Indexing files...
INFO: Project configuration:
INFO: 17 files indexed
INFO: 0 files ignored because of scm ignore settings
INFO: Quality profile for c: Sonar way
INFO: ------------- Run sensors on module democode
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=58ms
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1 (file:/var/lib/jenkins/.sonar/cache/a89f1943fc75b65becd9fb4ecab8d913/sonar-tsql-plugin.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of net.sf.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
INFO: Sensor JavaXmlSensor [java]
INFO: Sensor JavaXmlSensor [java] (done) | time=2ms
INFO: Sensor HTML [web]
INFO: Sensor HTML [web] (done) | time=11ms
INFO: Sensor gcov [cpp]
INFO: Parsing /var/lib/jenkins/workspace/ddsp_democode/./demo.gcov
INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
INFO: Total time: 9.417s
INFO: Final Memory: 21M/80M
INFO: ------------------------------------------------------------------------
ERROR: Error during SonarQube Scanner execution
java.lang.NullPointerException
	at org.sonar.api.batch.fs.internal.DefaultFilePredicates.is(DefaultFilePredicates.java:135)
	at com.sonar.cpp.plugin.gcov.GcovSensor.lambda$execute$2(GcovSensor.java:56)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
	at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at com.sonar.cpp.plugin.gcov.GcovSensor.scan(GcovSensor.java:75)
	at com.sonar.cpp.plugin.gcov.GcovSensor.execute(GcovSensor.java:52)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:400)
	at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:395)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:358)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:141)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at com.sun.proxy.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
	at org.sonarsource.scanner.cli.Main.main(Main.java:61)
ERROR:

@mpaladin let me know if you need more

Hi @peter.toft,

Could you share demo.gcov file?

demo.gcov ->

------------------------------------------------------------------------------
                       GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
ext_fct.c                                      5       4    80%   6
main.c                                         5       4    80%   8
------------------------------------------------------------------------------
TOTAL                                         10       8    80%
------------------------------------------------------------------------------

Hi @peter.toft,

you need to generate the coverage reports using gcov, not gcovr, as you can see in your demo.gcov you get only a summary. You need to call gcov for each of the source file, you can find many tutorial explaining how to generate gcov reports.

THANX a mil @mpaladin - I am on the right path now!

1 Like

@mpaladin and others - if adding cmake on top of this it becomes nasty (see e.g. https://stackoverflow.com/questions/13116488/detailed-guide-on-using-gcov-with-cmake-cdash), however
gcovr has an option -k that can be added which keeps the indivitual .gcov files, needed for SonarQube.
This is a very fast way though and it now plays with SonarQube - I used https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake with the “-k” addition.

Thanx for the help!!

1 Like