Sonar looks for build-wrapper even though it hasn't been configured

I have previously asked about a problem with build-wrapper (Build-wrapper doesn't record all compiled files, sometimes zero) but that topic is now closed. I have switched to not using build-wrapper anymore and it worked flawlessly for a while.

Now suddenly the sonar scanner complains that it doesn’t find bw-outputs\build-wrapper-dump.json. However, in sonar-project.properties I have replaced the line

sonar.cfamily.build-wrapper-output=bw-outputs

with

sonar.cfamily.compile-commands=build/compile_commands.json

so the scanner should not even use it anymore. Why would it want the build wrapper output? Where could this have been configured or written to that I have overlooked?

The scanner log says:

INFO: Using build-wrapper output: C:\Jenkins\workspace\...

and 30 seconds later it complains about the missing dump.

Hey there.

  • What version of SonarQube are you using?
  • Is it possible that that sonar.cfamily.build-wrapper-output slipped into your Jenkins job configuration (you can also pass analysis parameters here rather than a sonar-project.properties file)

The scanner should throw an error if it finds both sonar.cfamily.build-wrapper-output and sonar.cfamily.compile-commands. So it seems to only be discovering the former.

You might also try a local run to see if the behavior is duplicated outside of the Jenkins environment.

Hi Colin, thanks for the quick reply! I am using SonarQube server 8.9.8 and SonarScanner 4.7.0.2747.

I don’t see any build-wrapper config in the Jenkinsfile, and when running locally, it still says that it is using the buildwrapper output :frowning:

Ah, well there is one problem. Compilation database support was only introduced in SonarQube v9.0, with CPP-1428 so using SonarQube v8.9 LTS is simply going to ignore any reference to sonar.cfamily.compile-commands because it doesn’t actually exist in your version of SonarQube.

There is an experimental workaround documented in that ticket (to convert compile_commands to a build wrapper output) from before we officially supported compilation databases in the analyzer.

I have no idea how (or what) was working for you with SonarQube v8.9 LTS

Oh gee! Thanks a lot, I will look into it. Yeah, no idea why it was working before, maybe the old buildwrapper output was still in the repo and got cleaned at some point. To be honest, I never checked the log in its detail :innocent:

One more question: compilation database support is in SonarQube 9.x, so does it matter which SonarScanner I am using? Updating the scanner won’t help?

Correct, updating the scanner won’t help. The scanner mostly just downloads the “real” logic from the SonarQube server to execute analysis.

I have now tried the conversion approach with the given script (which I had to fix due to missing escapes). The result is a crash:

java.lang.NullPointerException
	at com.sonar.cpp.analyzer.MsvcDriver.onCapture(MsvcDriver.java:242)
	at com.sonar.cpp.plugin.CFamilySensor.process(CFamilySensor.java:590)
	at com.sonar.cpp.plugin.CFamilySensor.process(CFamilySensor.java:373)
	at com.sonar.cpp.plugin.CFamilySensor.execute(CFamilySensor.java:177)
	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.execute(ModuleSensorsExecutor.java:62)
	at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
	at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:392)
	at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:388)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:357)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:150)

I can’t do much with this… do you know why this is happening? Here is my python script as well:
convert-compile-commands.py.txt (1.1 KB)
(I had to add the txt extension, otherwise the upload wouldn’t work.)

HI @michael-brade,

To attempt at solving the crash, more information would be needed. Could you please share the full debug log for the sonar-scanner (pass option -X) , and the input (compilation database) and produced output. If you think this file contains private information, let us know, and we’ll send you a private message that will allow you to send it privately.

Thank you! Yes, I now have the log and the build-wrapper-dump.json, but not the compilation database :see_no_evil: It got deleted too quickly. And yes, please send me a private message.

Thank you for sharing. I have checked the produced build-wrapper.json and noticed few things:

  • there are 14 entries with rc.exe as executable (other than cl.exe), and they are most likely causing crashes. Could you remove them from either compile-commands.json or generated build-wrapper.json?
  • the env is missing the environment (like INCLUDE) variables for cl.exe. To capture proper variables you need to run conversion in the “Developer command prompt” or call vcvars64.bat to set up variables. Relevant MSVC docs.

Cool, I will try the first one with the next builds, probably on Friday. Your second point is already the case… without vcvars64.bat, not even the cmake would run. I guess I will have to look into what’s going on there.

Thanks :slight_smile:

little update: vcvars64.bat has to be called in every stage and sonar was a separate stage, therefore the variables were missing. However, the crash still happens. I’ll try without rc.exe next.

BTW, what exactly is in line 242 in MsvcDriver.java that is null?

little update: vcvars64.bat has to be called in every stage and sonar was a separate stage, therefore the variables were missing. However, the crash still happens. I’ll try without rc.exe next.

I apologize if I was unclear, the missing INCLUDE env (vcvars64.bat ), will lead the problems with analysis when it is running, but were not causing the crash.

BTW, what exactly is in line 242 in MsvcDriver.java that is null?

Output from the compiler probe is unexpected, missing elements that we assume will be there. rc.exe output is empty, so this is why I believe it is causing a crash.

I see. Thanks a lot. I have now filtered the rc.exe but it still crashes :frowning: However, the INCLUDE var is also still missing, so I need to analyze it further. Just for reference, here is the current Jenkinsfile part:

        stage('SonarQube Analysis') {
			when {
				not {
					triggeredBy 'TimerTrigger'
				}
			}

            steps {
				bat """
					call "${env.VS_VCVARS}"
					python.exe convert-compile-commands.py build\\compile_commands.json
				"""

				catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
					withSonarQubeEnv(SONAR_SERVER) {
						script {
							if (env.CHANGE_BRANCH) {
								// pull request
								bat "C:\\Jenkins\\sonar-scanner\\bin\\sonar-scanner.bat -X -Dsonar.projectVersion=${ BRANCH_NAME ==~ /feature-.+/ ? BRANCH_NAME + "-" + BUILD_NUMBER : VERSION} -Dsonar.pullrequest.branch=${env.CHANGE_BRANCH} -Dsonar.pullrequest.key=${env.CHANGE_ID} -Dsonar.pullrequest.base=${env.CHANGE_TARGET}"
							} else {
								// normal branch (usually master)
								bat "C:\\Jenkins\\sonar-scanner\\bin\\sonar-scanner.bat -X -Dsonar.projectVersion=${ BRANCH_NAME ==~ /feature-.+/ ? BRANCH_NAME + "-" + BUILD_NUMBER : VERSION} -Dsonar.branch.name=${BRANCH_NAME}"
							}
						}
                	}
				}

				timeout(time: 1, unit: 'HOURS') {
           			waitForQualityGate abortPipeline: true
          		}
            }
        }

Could you please check that the "executable": lines in the produced build_wrapper.json contain only cl.exe entry? To be extra safe, you could also check what is produced if you invoked this command in your CI: we are looking for a line with the version of the compiler.
You can also share the product file via PM and I could take a look.

Oh gee!!! I think I found the issue, at least it’s an obious error: python outputs

"cmd": [
        "'C:\\...

Note the extra quote. It came from the shlex.quote function, I have a fix in the pipeline. Let’s see…

Second, which command did you mean with “invoke this command in your CI:”? did you forget something after the colon? :innocent:

Not good news: environment is fixed, the wrong quote removed, but sonar still crashes. So we are back to square one. I think I now also understood what you meant with “this command”: if I run the executable command in the CI, I get:

Microsoft (R) C/C++-Optimierungscompiler Version 19.31.31104 für x64
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.

Syntax: cl [ Option... ] Dateiname... [ /link Linkeroption... ]

Is that what you would expect?

By command, I mean running the command from the build-wrapper-dump.json exactly as specified in the generated file, and preferably in the same place as the sonar-scanner is invoked.

"C:\\PROGRA~2\\MICROS~3\\2022\\PROFES~1\\VC\\Tools\\MSVC\\1431~1.311\\bin\\Hostx64\\x64\\cl.exe"

(Removed the additional quote).

jup, that’s exactly what I did to get the output of my last comment yesterday