Sonarlint seems to work fine but finds zero issues in all analyzed code

Please provide

  • Operating system: Win10
  • SonarLint plugin version: 4.11.1
  • Programming language you’re coding in: C
  • Is connected mode used: yes
    • Connected to SonarCloud or SonarQube (and which version): SonarQube v10.6 (92116) Developer Edition (though it does not work in disconnected mode either)

And a thorough description of the problem / question:
We are using SonarQube to analyze code for a project with about 100k LOC. In SQ, all issues are found and listed as expected. I installed SonarLint on some of the developers machines, set it up to connect to our SQ which worked fine, it guessed the correct project to bind to immediately and seemed to download all needed rules. I let cmake generate the compilation database which SonarLint immediately found and accepted. SonarLint seems to run fine but fails to find a single issue - while it runs all its tests as expected and seems to be happy with all of its settings, it always returns “Analysis detected 0 issues and 0 Security Hotspots in 910ms” which is not true - the same file has multiple issues displayed in SonarQube. If I add an issue by actively typing something in the code, e.g. typing // TODO while Rule S1135 is active, does not add any problems and there are still zero issues found.
When i disconnect SonarLint from SonarQube, it still does not work.

Here is a verbose log, including showAnalyzerLogs and showVerboseLogs. i redacted sensitive data.
due to character limit in this forum, please find the log here: here

Hello @jat_malte,

Could you share a reproducer with the content of the analysis privately so we can try to reproduce it on our side? From the logs, we can not see anything out of the ordinary.

You would need to add to your settings.json the following

"sonarlint.analyzerProperties": {"sonar.cfamily.reproducer" : "D:\\malte\\GIT\\ems\\canopen\\can_sync.c"}

On the same place where you got the logs you shared, you will see a file sonar-cfamily.reproducer written into a temporary directory. When you have it, I can send you a private message to send it to us.

Thanks.

I have the file. Please instruct me how to send it to you.

Hello,

Thanks for the reproducer. From what I can see, the probe is missing a few macros that we expect and need to resolve the size of some types.

  __SIZEOF_INT__
  __SIZEOF_LONG__
  __SIZEOF_LONG_LONG__
  __SIZEOF_FLOAT__
  __SIZEOF_DOUBLE__
  __SIZEOF_LONG_DOUBLE__

Hence, the analyzer stops early. There is surely an improvement to be made because the error is not found on the logs.

https://sonarsource.atlassian.net/browse/CPP-5805

On the other hand.

This makes me think the compiler returns these macros on your CI. Are they the same compiler and version, with the same set of flags? Do you use build-wrapper on the CI?

If you could share the output from build-wrapper from the CI, and the compile-commands from your VSCode setup (same private message), maybe we can spot if there is something different on the set of arguments.

We are not using a wrapper - neither in the CI, nor in Sonarlint. SQ (or better, SonarScanner) seems happy with that.
We are building with cmake, in the CI and in VSCODE. I can send you the compilation database, if that helps?

Yes, please, send both compilation databases (CI and local) if you can.

as there is not much of a secret in them, i can put them here. i reduced them to the same file.
this version is used in the CI:

{
  "directory": "/home/gitlab-runner/builds/FUEENz7S/0/<redacted>/build_debug/canopen",
  "command": "/home/gitlab-runner/ti/compilers/ti-cgt-c2000_6.4.12/bin/cl2000 --compile_only --c_file=/home/gitlab-runner/builds/FUEENz7S/0/<redacted>/ems/canopen/can_sync.c -DAS_1 -DBUILD_WITH_CMAKE -D_DEBUG -D_FLASH --include_path=/home/gitlab-runner/ti/compilers/ti-cgt-c2000_6.4.12/include --include_path=/home/gitlab-runner/builds/FUEENz7S/0/<redacted>/ems/canopen --include_path=<many internal includes> --c99 --relaxed_ansi --silicon_version=28 --large_memory_model --unified_memory --float_support=fpu32 --tmu_support=tmu0 --cla_support=cla1 --opt_level=1 --opt_for_speed=5 --fp_mode=relaxed --advice:performance=all --symdebug:dwarf --diag_wrap=off --diag_warning=225 --display_error_number --preproc_with_compile --emit_warnings_as_errors --output_file=CMakeFiles/canopen.dir/can_sync.c.obj",
  "file": "/home/gitlab-runner/builds/FUEENz7S/0/<redacted>/ems/canopen/can_sync.c",
  "output": "canopen/CMakeFiles/canopen.dir/can_sync.c.obj"
},

and this version is used locally:

    {
      "directory": "C:/Users/Malte/GIT/ems/build_debug/canopen",
      "command": "C:/ti/kompiler//ti-cgt-c2000_6.4.12/bin/cl2000.exe --compile_only --c_file=C:/Users/Malte/GIT/ems/canopen/can_sync.c -DAS_1 -DBUILD_WITH_CMAKE -D_DEBUG -D_FLASH --include_path=C:/ti/kompiler/ti-cgt-c2000_6.4.12/include --include_path=C:/Users/Malte/GIT/ems/canopen --include_path=<many internal includes> --c99 --relaxed_ansi --silicon_version=28 --large_memory_model --unified_memory --float_support=fpu32 --tmu_support=tmu0 --cla_support=cla1 --opt_level=1 --opt_for_speed=5 --fp_mode=relaxed --advice:performance=all --symdebug:dwarf --diag_wrap=off --diag_warning=225 --display_error_number --preproc_with_compile --emit_warnings_as_errors --output_file=CMakeFiles/canopen.dir/can_sync.c.obj",
      "file": "C:/Users/Malte/GIT/ems/canopen/can_sync.c",
      "output": "canopen/CMakeFiles/canopen.dir/can_sync.c.obj"
    },

as you can see, they are identical (ignoring folder names, and ignoring the .exe on windows). there is an important difference though: sonarlint in vscode refuses to work without seeing this file, while sonarscanner in the CI has absolutely no problem without having a compile database. in fact, in our CI, sonarscanner would not be able to access this file at all, but still managed to analyze the source and find issues, though none of them related to the missing defines.

we then added the option -Dsonar.cfamily.compile-commands to the sonarscanner command line, and sure enough it does now fail with the same defines missing. so now, both sonarscanner AND sonarlint don’t work, sonarscanner giving out the error that the defines are not found, and sonarlint silently failing. this is an improvement as we can now go about adding those defines in to make both of them happy at once, I hope. The problem is now narrowed down to the compiler using intrinsic defines which it will not list when probed.

still this raises the question: if sonar.cfamily.compile-commands is not used and sonarscanner does not get a compilation database - what does it compile with? does it compile at all?

also, if someone else finds this thread in the future: newer versions of the c2000 compiler do actually report the correct defines when probed, this error will happen with older versions of the c2000 compiler which do use the defines internally, but dont report them when probed.

Since SonarQube 10.6, the CFamily analyzer can analyze C and C++ code without a compilation database. This feature is called AutoConfig and is mainly aimed at projects that use unsupported compilers, such as older c2000 compilers.

If you manage to fix the probing (by manually defining the macros, as you suggested), then all the better. But you also have AutoConfig as a fallback [1]. Unfortunately, it will not fix the issue in SonarLint.

Since this is a relatively new feature, may I ask for a snippet from the logs that looks like this?

07:45:04.162 INFO  C and C++ analysis quality score: 81.81/100
07:45:04.162 INFO  Analysis measures statistics:
94.39% of classes were parsed successfully (32 out of 570 have parsing errors)
59.1% of functions were parsed successfully (29808 out of 72880 have parsing errors)
93.23% of statements were parsed successfully (791461 out of 11684962 have parsing errors)
93.87% of the project includes directives were resolved (2928 out of 47762 were not resolved)
16 external includes directives were not resolved
0 modules imports were not resolved
0 header units were not resolved
07:45:04.221 INFO  Missing headers stats: [syscalls/(487);hal/(146);soc/(97);bs_tracing.h(97);driverlib/(84);bs_types.h(74);tinycrypt/(70);arm_math.h(65);fsl_clock.h(47);xtensa/(46);ti/(42);openthread/(42);hardware/(42);stm32_ll_rcc.h(34);thrift/(33);stm32_ll_bus.h(33);fsl_common.h(33);zcbor_common.h(32);ti/drivers/(30);stm32_ll_pwr.h(30)]
For better analysis quality, consider providing `sonar.cfamily

It gives a measure of how well the analyzer managed to understand the code even without the compilation database.

[1] AutoConfig can be fine-tuned to improve the quality score.

Sure. Here is the log before using the compilation database, using autoconfig, which seems to ignore the missing defines:

(note that the missing header file “version.h” is not a fault of SQ as the file was actually really missing).

and here is the log after enabling use of the compilation database, using the actual compiler and therefore failing to find the defines:

Note that the log with the compilation failure reports 100% on all analysis measures and it also passes the quality gate. i am not sure if this is a bug or a feature :slight_smile:

This is similar to this issue, which finds no issues if it cannot analyze a file for encoding reasons, and then reports zero issues back to pass the quality gate. maybe sonarlint should report an issue when it cannot analyze a file for any reason, be it missing includes or encoding or being unable to open a file because of a permission issue?

Thanks! Very useful

For the missing predefines, I have created a ticket, but I can’t give any estimated fix date given this is an older version of the compiler.
https://sonarsource.atlassian.net/browse/CPP-5810

Note that the log with the compilation failure reports 100% on all analysis measures and it also passes the quality gate. i am not sure if this is a bug or a feature :slight_smile:

Agreed, it is odd to say “ERROR Compiler not compatible” and then move on and finish with success. I have created another ticket.

https://sonarsource.atlassian.net/browse/CPP-5811

In the meanwhile:

which seems to ignore the missing defines:

It has its own, based on a default assumption of x86_64. These are probably wrong since you mentioned this is an embedded platform (32 bits I believe, with 16 bits bytes?). And note that we do not support 16-bits bytes so we may have some FP given our assumptions about the size of char.

Anyway, to be closer, for AutoConfig, you can choose a more similar platform using the following parameters:

sonar.cfamily.customTargetArch=msp430 # I think this is the closest we have in term of type sizes
sonar.cfamily.customTargetVendor=unknown
sonar.cfamily.customTargetSystem=unknown
sonar.cfamily.customTargetEnv=eabi

yes, exactly, this is a c2000 thing with 16 bit bytes. as an added bonus, the (internal) define for the byte size is “1” because the c2000 compiler calculates everything in WORDs and not in bytes, so a char is 1 and an int is 1 (both using 16-bit values) and a long is 2 (using 4 bytes), so even if we give the “correct” defines to sonarscanner in some way, it still finds issues on shift operations, because the defines are “wrong” by factor two. also a float and a double have the same size… this compiler is a mess. :smiley: we will probably need a wrapper to double the defines for sonarscanner.