diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs
index dafda9a8f2ab..577eed2a0c8c 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpAutobuilder.cs
@@ -15,6 +15,7 @@ public class CSharpAutobuildOptions : AutobuildOptionsShared
private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_";
public bool Buildless { get; }
+ public string? Binlog { get; }
public override Language Language => Language.CSharp;
@@ -29,7 +30,7 @@ public CSharpAutobuildOptions(IBuildActions actions) : base(actions)
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false) ||
actions.GetEnvironmentVariable(buildModeEnvironmentVariable)?.ToLower() == "none";
-
+ Binlog = actions.GetEnvironmentVariable(extractorOptionPrefix + "BINLOG");
}
}
diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
index 7c4f1d681773..515fecd5bec6 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj
@@ -6,6 +6,7 @@
+
diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs
index 5b844e6cf6c8..489ecccfd40b 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/StandaloneBuildRule.cs
@@ -10,7 +10,14 @@ internal class StandaloneBuildRule : IBuildRule
{
public BuildScript Analyse(IAutobuilder builder, bool auto)
{
- return BuildScript.Create(_ => Semmle.Extraction.CSharp.Standalone.Program.Main([]));
+ if (builder.Options.Binlog is string binlog)
+ {
+ return BuildScript.Create(_ => Semmle.Extraction.CSharp.Driver.Main(["--binlog", binlog]));
+ }
+ else
+ {
+ return BuildScript.Create(_ => Semmle.Extraction.CSharp.Standalone.Program.Main([]));
+ }
}
}
}
diff --git a/csharp/codeql-extractor.yml b/csharp/codeql-extractor.yml
index 6c3285c412b9..e33f8feae08b 100644
--- a/csharp/codeql-extractor.yml
+++ b/csharp/codeql-extractor.yml
@@ -65,3 +65,6 @@ options:
- progress+++
type: string
pattern: "^(off|errors|warnings|(info|progress)|(debug|progress\\+)|(trace|progress\\+\\+)|progress\\+\\+\\+)$"
+ binlog:
+ title: Binlog
+ type: string
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs
index 2f21716284f0..281ce9e93491 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs
@@ -312,8 +312,6 @@ public virtual void Dispose()
else
Logger.Log(Severity.Info, "EXTRACTION SUCCEEDED in {0}", stopWatch.Elapsed);
- Logger.Dispose();
-
compilationTrapFile?.Dispose();
}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/BinaryLogAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/BinaryLogAnalyser.cs
new file mode 100644
index 000000000000..23a52f7fa1ec
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/BinaryLogAnalyser.cs
@@ -0,0 +1,22 @@
+using Microsoft.CodeAnalysis.CSharp;
+using Semmle.Util.Logging;
+
+namespace Semmle.Extraction.CSharp
+{
+ public class BinaryLogAnalyser : Analyser
+ {
+ public BinaryLogAnalyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix, PathTransformer pathTransformer)
+ : base(pm, logger, addAssemblyTrapPrefix, pathTransformer)
+ {
+ }
+
+ public void Initialize(string cwd, string[] args, string outputPath, CSharpCompilation compilationIn, CommonOptions options)
+ {
+ compilation = compilationIn;
+ extractor = new BinaryLogExtractor(cwd, args, outputPath, Logger, PathTransformer, options);
+ this.options = options;
+ LogExtractorInfo(Extraction.Extractor.Version);
+ SetReferencePaths();
+ }
+ }
+}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
index f6913103ad8c..536fb3404efd 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
@@ -8,6 +8,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Basic.CompilerLog.Util;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
@@ -97,60 +98,120 @@ public static ExitCode Run(string[] args)
stopwatch.Start();
var options = Options.CreateWithEnvironment(args);
- var workingDirectory = Directory.GetCurrentDirectory();
- var compilerArgs = options.CompilerArguments.ToArray();
-
using var logger = MakeLogger(options.Verbosity, options.Console);
- var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
- var pathTransformer = new PathTransformer(canonicalPathCache);
-
- using var analyser = new TracingAnalyser(new LogProgressMonitor(logger), logger, options.AssemblySensitiveTrap, pathTransformer);
-
try
{
- if (options.ProjectsToLoad.Any())
+ var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
+ var pathTransformer = new PathTransformer(canonicalPathCache);
+
+ if (options.BinaryLogPath is string binlogPath)
{
- AddSourceFilesFromProjects(options.ProjectsToLoad, options.CompilerArguments, logger);
+ logger.LogInfo(" Running binary log analysis.");
+ return RunBinaryLogAnalysis(stopwatch, binlogPath, options, logger, pathTransformer);
}
-
- var compilerVersion = new CompilerVersion(options);
-
- if (compilerVersion.SkipExtraction)
+ else
{
- logger.Log(Severity.Warning, " Unrecognized compiler '{0}' because {1}", compilerVersion.SpecifiedCompiler, compilerVersion.SkipReason);
- return ExitCode.Ok;
+ logger.LogInfo(" Running tracing analysis.");
+ return RunTracingAnalysis(stopwatch, options, logger, canonicalPathCache, pathTransformer);
}
+ }
+ catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
+ {
+ logger.Log(Severity.Error, " Unhandled exception: {0}", ex);
+ return ExitCode.Errors;
+ }
+ }
- var compilerArguments = CSharpCommandLineParser.Default.Parse(
- compilerVersion.ArgsWithResponse,
- workingDirectory,
- compilerVersion.FrameworkPath,
- compilerVersion.AdditionalReferenceDirectories
- );
+ private static ExitCode RunBinaryLogAnalysis(Stopwatch stopwatch, string binlogPath, Options options, ILogger logger, PathTransformer pathTransformer)
+ {
+ using var fileStream = new FileStream(binlogPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ // Filter out compiler calls that aren't interesting for examination
+ static bool filter(CompilerCall compilerCall)
+ {
+ return compilerCall.IsCSharp &&
+ compilerCall.Kind == CompilerCallKind.Regular;
+ }
- if (compilerArguments is null)
+ using var reader = BinaryLogReader.Create(fileStream);
+ var allCompilationData = reader.ReadAllCompilationData(filter);
+
+ var exitCode = ExitCode.Ok;
+
+ logger.LogInfo($" Found {allCompilationData.Count} compilations in binary log");
+
+ foreach (var compilationData in allCompilationData)
+ {
+ if (compilationData.GetCompilationAfterGenerators() is not CSharpCompilation compilation)
{
- var sb = new StringBuilder();
- sb.Append(" Failed to parse command line: ").AppendList(" ", compilerArgs);
- logger.Log(Severity.Error, sb.ToString());
- ++analyser.CompilationErrors;
- return ExitCode.Failed;
+ logger.LogError(" Compilation data is not C#");
+ continue;
}
- if (!analyser.BeginInitialize(compilerVersion.ArgsWithResponse))
+ var compilerCall = compilationData.CompilerCall;
+ var compilerArgs = compilerCall.GetArguments();
+ var args = reader.ReadCommandLineArguments(compilerCall);
+
+ using var analyser = new BinaryLogAnalyser(new LogProgressMonitor(logger), logger, options.AssemblySensitiveTrap, pathTransformer);
+
+ var exit = Analyse(stopwatch, analyser, options,
+ references => [() => compilation.References.ForEach(r => references.Add(r))],
+ (analyser, syntaxTrees) => [() => syntaxTrees.AddRange(compilation.SyntaxTrees)],
+ (syntaxTrees, references) => compilation,
+ (compilation, options) => analyser.Initialize(compilerCall.ProjectDirectory, compilerArgs?.ToArray() ?? [], TracingAnalyser.GetOutputName(compilation, args), compilation, options),
+ () => { });
+
+ if (exitCode == ExitCode.Ok && exit != ExitCode.Ok)
{
- logger.Log(Severity.Info, "Skipping extraction since files have already been extracted");
- return ExitCode.Ok;
+ exitCode = ExitCode.Errors;
}
+ }
+ return exitCode;
+ }
- return AnalyseTracing(workingDirectory, compilerArgs, analyser, compilerArguments, options, canonicalPathCache, stopwatch);
+ private static ExitCode RunTracingAnalysis(Stopwatch stopwatch, Options options, ILogger logger, CanonicalPathCache canonicalPathCache, PathTransformer pathTransformer)
+ {
+ var workingDirectory = Directory.GetCurrentDirectory();
+ var compilerArgs = options.CompilerArguments.ToArray();
+
+ using var analyser = new TracingAnalyser(new LogProgressMonitor(logger), logger, options.AssemblySensitiveTrap, pathTransformer);
+
+ if (options.ProjectsToLoad.Any())
+ {
+ AddSourceFilesFromProjects(options.ProjectsToLoad, options.CompilerArguments, logger);
}
- catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
+
+ var compilerVersion = new CompilerVersion(options);
+
+ if (compilerVersion.SkipExtraction)
{
- logger.Log(Severity.Error, " Unhandled exception: {0}", ex);
- return ExitCode.Errors;
+ logger.Log(Severity.Warning, " Unrecognized compiler '{0}' because {1}", compilerVersion.SpecifiedCompiler, compilerVersion.SkipReason);
+ return ExitCode.Ok;
}
+
+ var compilerArguments = CSharpCommandLineParser.Default.Parse(
+ compilerVersion.ArgsWithResponse,
+ workingDirectory,
+ compilerVersion.FrameworkPath,
+ compilerVersion.AdditionalReferenceDirectories
+ );
+
+ if (compilerArguments is null)
+ {
+ var sb = new StringBuilder();
+ sb.Append(" Failed to parse command line: ").AppendList(" ", compilerArgs);
+ logger.Log(Severity.Error, sb.ToString());
+ ++analyser.CompilationErrors;
+ return ExitCode.Failed;
+ }
+
+ if (!analyser.BeginInitialize(compilerVersion.ArgsWithResponse))
+ {
+ logger.Log(Severity.Info, "Skipping extraction since files have already been extracted");
+ return ExitCode.Ok;
+ }
+
+ return AnalyseTracing(workingDirectory, compilerArgs, analyser, compilerArguments, options, canonicalPathCache, stopwatch);
}
private static void AddSourceFilesFromProjects(IEnumerable projectsToLoad, IList compilerArguments, ILogger logger)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs
index 4fafffe98333..7f3815520d62 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Options.cs
@@ -32,6 +32,11 @@ public sealed class Options : CommonOptions
///
public bool AssemblySensitiveTrap { get; private set; } = false;
+ ///
+ /// The path to the binary log file, or null if unspecified.
+ ///
+ public string? BinaryLogPath { get; set; }
+
public static Options CreateWithEnvironment(string[] arguments)
{
var options = new Options();
@@ -65,6 +70,9 @@ public override bool HandleOption(string key, string value)
case "load-sources-from-project":
ProjectsToLoad.Add(value);
return true;
+ case "binlog":
+ BinaryLogPath = value;
+ return true;
default:
return base.HandleOption(key, value);
}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs
index c609b2ba100a..963952c2b733 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/TracingAnalyser.cs
@@ -110,8 +110,8 @@ private bool LogRoslynArgs(IEnumerable roslynArgs, string extractorVersi
/// Information about the compilation.
/// Cancellation token required.
/// The filename.
- private static string GetOutputName(CSharpCompilation compilation,
- CSharpCommandLineArguments commandLineArguments)
+ internal static string GetOutputName(CSharpCompilation compilation,
+ CommandLineArguments commandLineArguments)
{
// There's no apparent way to access the output filename from the compilation,
// so we need to re-parse the command line arguments.
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/paket.references b/csharp/extractor/Semmle.Extraction.CSharp/paket.references
index 70cd7de8821f..d53881096fdf 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/paket.references
+++ b/csharp/extractor/Semmle.Extraction.CSharp/paket.references
@@ -1,3 +1,3 @@
Microsoft.Build
Microsoft.CodeAnalysis.CSharp
-
+Basic.CompilerLog.Util
\ No newline at end of file
diff --git a/csharp/extractor/Semmle.Extraction/Extractor/BinaryLogExtractor.cs b/csharp/extractor/Semmle.Extraction/Extractor/BinaryLogExtractor.cs
new file mode 100644
index 000000000000..6788ae4dfd49
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction/Extractor/BinaryLogExtractor.cs
@@ -0,0 +1,19 @@
+using Semmle.Util.Logging;
+
+namespace Semmle.Extraction
+{
+ public class BinaryLogExtractor : Extractor
+ {
+ public override ExtractorMode Mode { get; }
+
+ public BinaryLogExtractor(string cwd, string[] args, string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options)
+ : base(cwd, args, outputPath, [], logger, pathTransformer)
+ {
+ Mode = ExtractorMode.BinaryLog;
+ if (options.QlTest)
+ {
+ Mode |= ExtractorMode.QlTest;
+ }
+ }
+ }
+}
diff --git a/csharp/extractor/Semmle.Extraction/Extractor/ExtractorMode.cs b/csharp/extractor/Semmle.Extraction/Extractor/ExtractorMode.cs
index 52ef15f52d4d..cc1f5cc04132 100644
--- a/csharp/extractor/Semmle.Extraction/Extractor/ExtractorMode.cs
+++ b/csharp/extractor/Semmle.Extraction/Extractor/ExtractorMode.cs
@@ -12,5 +12,6 @@ public enum ExtractorMode
Standalone = 1,
Pdb = 2,
QlTest = 4,
+ BinaryLog = 8,
}
}
diff --git a/csharp/paket.dependencies b/csharp/paket.dependencies
index 3b93065a4fbd..4d76c4e918dc 100644
--- a/csharp/paket.dependencies
+++ b/csharp/paket.dependencies
@@ -4,6 +4,7 @@ source https://api.nuget.org/v3/index.json
# behave like nuget in choosing transitive dependency versions
strategy: min
+nuget Basic.CompilerLog.Util
nuget Mono.Posix.NETStandard
nuget Newtonsoft.Json
nuget xunit
@@ -17,4 +18,4 @@ nuget System.Net.Primitives
nuget System.Security.Principal
nuget System.Threading.ThreadPool
nuget System.IO.FileSystem
-nuget GitInfo 3.3.3
+nuget GitInfo 3.3.3
\ No newline at end of file
diff --git a/csharp/paket.lock b/csharp/paket.lock
index 060187c166f2..e0ee9f4eb7f6 100644
--- a/csharp/paket.lock
+++ b/csharp/paket.lock
@@ -3,9 +3,21 @@ STRATEGY: MIN
RESTRICTION: == net8.0
NUGET
remote: https://api.nuget.org/v3/index.json
+ Basic.CompilerLog.Util (0.7.3)
+ MessagePack (>= 2.5.129)
+ Microsoft.CodeAnalysis (>= 4.8)
+ Microsoft.CodeAnalysis.CSharp (>= 4.8)
+ Microsoft.CodeAnalysis.VisualBasic (>= 4.8)
+ Microsoft.Extensions.ObjectPool (>= 7.0.13)
+ MSBuild.StructuredLogger (>= 2.2.235)
GitInfo (3.3.3)
ThisAssembly.Constants (>= 1.4.1)
Humanizer.Core (2.14.1)
+ MessagePack (2.5.129)
+ MessagePack.Annotations (>= 2.5.129)
+ Microsoft.NET.StringTools (>= 17.6.3)
+ System.Runtime.CompilerServices.Unsafe (>= 6.0)
+ MessagePack.Annotations (2.5.129)
Microsoft.Bcl.AsyncInterfaces (7.0)
Microsoft.Build (17.8.3)
Microsoft.Build.Framework (>= 17.8.3)
@@ -17,6 +29,11 @@ NUGET
System.Security.Principal.Windows (>= 5.0)
System.Threading.Tasks.Dataflow (>= 7.0)
Microsoft.Build.Framework (17.8.3)
+ Microsoft.Build.Utilities.Core (17.5)
+ Microsoft.Build.Framework (>= 17.5)
+ Microsoft.NET.StringTools (>= 17.5)
+ System.Collections.Immutable (>= 6.0)
+ System.Configuration.ConfigurationManager (>= 6.0)
Microsoft.CodeAnalysis (4.8)
Microsoft.CodeAnalysis.CSharp.Workspaces (4.8)
Microsoft.CodeAnalysis.VisualBasic.Workspaces (4.8)
@@ -48,6 +65,7 @@ NUGET
System.Threading.Channels (>= 7.0)
Microsoft.CodeCoverage (17.9)
Microsoft.CSharp (4.7)
+ Microsoft.Extensions.ObjectPool (7.0.13)
Microsoft.NET.StringTools (17.8.3)
Microsoft.NET.Test.Sdk (17.9)
Microsoft.CodeCoverage (>= 17.9)
@@ -65,6 +83,9 @@ NUGET
System.Runtime (>= 4.3)
Microsoft.Win32.SystemEvents (7.0)
Mono.Posix.NETStandard (1.0)
+ MSBuild.StructuredLogger (2.2.235)
+ Microsoft.Build.Framework (>= 17.5)
+ Microsoft.Build.Utilities.Core (>= 17.5)
Newtonsoft.Json (13.0.3)
System.Collections.Immutable (7.0)
System.Composition (7.0)
diff --git a/csharp/tools/run-dotnet.sh b/csharp/tools/run-dotnet.sh
new file mode 100755
index 000000000000..b96be3162e50
--- /dev/null
+++ b/csharp/tools/run-dotnet.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+set -eu
+
+echo Args: "$@"
+$@ || exit $?
diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua
index a48a93c073c8..68b8713c3e16 100644
--- a/csharp/tools/tracing-config.lua
+++ b/csharp/tools/tracing-config.lua
@@ -1,10 +1,28 @@
function RegisterExtractorPack(id)
+ -- local charset = {} do -- [0-9a-zA-Z]
+ -- for c = 48, 57 do table.insert(charset, string.char(c)) end
+ -- for c = 65, 90 do table.insert(charset, string.char(c)) end
+ -- for c = 97, 122 do table.insert(charset, string.char(c)) end
+ -- end
+
+ -- function RandomString(length)
+ -- if not length or length <= 0 then return '' end
+ -- math.randomseed(os.clock()^5)
+ -- return RandomString(length - 1) .. charset[math.random(1, #charset)]
+ -- end
+
+ function RandomString(length)
+ return '1234'
+ end
+
function Exify(path)
if OperatingSystem == 'windows' then return path .. '.exe' else return path end
end
local extractor = Exify(GetPlatformToolsDirectory() .. 'Semmle.Extraction.CSharp.Driver')
+ local dotnetScript = 'tools' .. PathSep .. 'run-dotnet.sh'
+
local function isDotnet(name)
return name == 'dotnet' or name == 'dotnet.exe'
end
@@ -27,6 +45,50 @@ function RegisterExtractorPack(id)
return path:match('%.exe$') or path:match('%.dll')
end
+ local function isBinLogArg(arg)
+ return arg:match('^[-/]bl:.*$')
+ -- TODO: handle other variants of bl, such as
+ -- bl without file name too, or
+ -- bl:output.binlog;ProjectImports=ZipFile, or
+ -- binaryLogger:...
+ end
+
+ function DotnetMatcherBuildBinaryLog(compilerName, compilerPath, compilerArguments,
+ _languageId)
+ if not isDotnet(compilerName) then
+ return nil
+ end
+
+ local filename = nil
+ local argv = compilerArguments.argv
+ if OperatingSystem == 'windows' then
+ -- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments
+ -- or, at least, that it is close enough
+ argv = NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
+ end
+
+ -- TODO: do we need to be more specific about the command that we're intercepting? Is `-bl` specific to `dotnet build`?
+ for i, arg in ipairs(argv) do
+ if isBinLogArg(arg) then
+ filename = string.sub(arg, 5) -- TODO: fix getting the filename
+ break
+ end
+ end
+
+ if filename then
+ local extractorArgs = { '--binlog', filename }
+ return {
+ order = ORDER_AFTER,
+ invocation = {
+ path = AbsolutifyExtractorPath(id, extractor),
+ arguments = {
+ argv = extractorArgs
+ }
+ }
+ }
+ end
+ end
+
function DotnetMatcherBuild(compilerName, compilerPath, compilerArguments,
_languageId)
if not isDotnet(compilerName) then
@@ -59,6 +121,14 @@ function RegisterExtractorPack(id)
argv =
NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
end
+
+ for i, arg in ipairs(argv) do
+ if isBinLogArg(arg) then
+ Log(1, 'Found binlog argument in dotnet command line, not changing command')
+ return nil
+ end
+ end
+
for i, arg in ipairs(argv) do
-- if dotnet is being used to execute any application except dotnet itself, we should
-- not inject any flags.
@@ -115,29 +185,28 @@ function RegisterExtractorPack(id)
end
end
if match then
- local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' }
+ -- TODO: Add real temporary file name
+ local injections = { '-bl:codeql_' .. RandomString(15) .. '.binlog' }
if dotnetRunNeedsSeparator then
table.insert(injections, '--')
end
- if dotnetRunInjectionIndex == nil then
- -- Simple case; just append at the end
- return {
- order = ORDER_REPLACE,
- invocation = BuildExtractorInvocation(id, compilerPath, compilerPath, compilerArguments, nil,
- injections)
- }
- end
- -- Complex case; splice injections into the middle of the command line
+ -- Adding compiler path to the arguments. This is needed to execute the same `dotnet` that we traced.
+ table.insert(argv, 1, compilerPath)
+
for i, injectionArg in ipairs(injections) do
- table.insert(argv, dotnetRunInjectionIndex + i - 1, injectionArg)
+ if dotnetRunInjectionIndex == nil then
+ table.insert(argv, injectionArg)
+ else
+ table.insert(argv, dotnetRunInjectionIndex + i, injectionArg)
+ end
end
if OperatingSystem == 'windows' then
return {
order = ORDER_REPLACE,
invocation = {
- path = AbsolutifyExtractorPath(id, compilerPath),
+ path = AbsolutifyExtractorPath(id, compilerPath), -- TODO: support windows too
arguments = {
commandLineString = ArgvToCommandLineString(argv)
}
@@ -147,7 +216,7 @@ function RegisterExtractorPack(id)
return {
order = ORDER_REPLACE,
invocation = {
- path = AbsolutifyExtractorPath(id, compilerPath),
+ path = AbsolutifyExtractorPath(id, dotnetScript),
arguments = {
argv = argv
}
@@ -221,6 +290,7 @@ function RegisterExtractorPack(id)
}
local posixMatchers = {
DotnetMatcherBuild,
+ DotnetMatcherBuildBinaryLog,
CreatePatternMatcher({ '^mcs%.exe$', '^csc%.exe$' }, MatchCompilerName,
extractor, {
prepend = { '--compiler', '"${compiler}"' },