CFamily Plugin crashing after update from SQ 7.9.6 to 8.9.6

Versions

  • Sonarqube 8.9.6
  • Sonarscanner for MSBuild 5.4
  • build-wrapper, version 6.20 (win-x86-64)
  • Java openjdk version “11.0.14” 2022-01-18
  • CFamily plugin version: 6.20.2.38358 (bundled with SQ 8.9.6)

Error

When analysing C++ code, scanner crashes. Excluding the analysed file just let’s it crash on another file next time. Seems to be arbitrary. Could not find anything common with the c++ files.

##[error]ERROR: Exception in thread pool-3-thread-5
ERROR: Exception in thread pool-3-thread-5
##[error]com.sonar.cpp.analyzer.Analyzer$AnalyzerException: Exit code != 0: [...]
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:132)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:52)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:129)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:52)
	at com.sonar.cpp.plugin.CFamilySensor.lambda$process$8(CFamilySensor.java:724)
com.sonar.cpp.analyzer.Analyzer$AnalyzerException: Exit code != 0: [...]
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:132)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:52)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:129)
	at com.sonar.cpp.analyzer.Subprocess.execute(Subprocess.java:52)
	at com.sonar.cpp.plugin.CFamilySensor.lambda$process$8(CFamilySensor.java:724)
##[error]at com.sonar.cpp.analyzer.AnalysisExecutor.lambda$submit$0(AnalysisExecutor.java:59)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at com.sonar.cpp.analyzer.AnalysisExecutor.lambda$submit$0(AnalysisExecutor.java:59)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
##[error]at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
##[error]at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
##[error]at java.base/java.lang.Thread.run(Thread.java:829)
	at java.base/java.lang.Thread.run(Thread.java:829)

Setting sonar.cfamily.threads=1 does not make a difference. sonar-cfamily-reproducer.zip is available privately if necessary.

Hello @martinh2011,

I sent you a private message where you can share the reproducer zip.

Thanks,

Hi @martinh2011,

Thanks for sharing the reproducer.
Untill we have a deeper look at it, feel free to exlude the file from analysis to unblock it.

Thanks,

Hi @Abbas
Thanks for the update. I already excluded about 30 source files. I exclude the file where it crashes, run the analysis again and it crashes on another c++ file :frowning:

Hi @martinh2011,

Thanks for the reproducer file!

The crash is due to two patterns you have, that are accepted by MSVC but are technically not valid C++ code and not handled by our tool.

Namespace qualified constructors

You prefix the constructors with the namespace. A minimal example would be this:

namespace A { struct S; }
struct A::S {
  A::S() = default;
  // instead of
  S() = default;
};

I created a ticket, to handle that on our side. We don’t have an ETA for it at the moment though.

Qualified member function inside a class declaration

You sometime prefix the member functions with the name of the class inside the class declaration:

struct S {
  void S::f();
  // instead of
  void f();
};

I created a ticket on our side, to handle that pattern on our side too. We don’t have an ETA for it at the moment either.

3 Likes

Hi @Fred_Tingaud thanks for the analysis. I will check (and apply) your workarounds first thing tomorrow morning.

A quick update: using qualified names (e.g. S::f) in class works.

There’s one subtility for constructors: In the previous example, it should be A::S::S (the first S is the class name, the second is the constructor name). Fixing this should allow the analysis to succeed.

Using the short, unqualified version (f and just S) is however probably better as it is more widely supported by compilers.

We’ll try to support the alternative version A::S but we do not have an ETA for this fix.