Skip to content

Commit 2bb9e48

Browse files
committed
C#: Handle dotnet exec csc.dll and the likes in the Lua tracer
1 parent 40d25cb commit 2bb9e48

File tree

1 file changed

+78
-26
lines changed

1 file changed

+78
-26
lines changed

csharp/tools/tracing-config.lua

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
function RegisterExtractorPack(id)
22
local extractor = GetPlatformToolsDirectory() ..
3-
'Semmle.Extraction.CSharp.Driver'
3+
'Semmle.Extraction.CSharp.Driver'
44
if OperatingSystem == 'windows' then extractor = extractor .. '.exe' end
55

66
function DotnetMatcherBuild(compilerName, compilerPath, compilerArguments,
@@ -24,7 +24,7 @@ function RegisterExtractorPack(id)
2424
-- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments
2525
-- or, at least, that it is close enough
2626
argv =
27-
NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
27+
NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
2828
end
2929
for i, arg in ipairs(argv) do
3030
-- dotnet options start with either - or / (both are legal)
@@ -39,8 +39,8 @@ function RegisterExtractorPack(id)
3939
return {
4040
order = ORDER_REPLACE,
4141
invocation = BuildExtractorInvocation(id, compilerPath,
42-
compilerPath,
43-
compilerArguments, nil, {
42+
compilerPath,
43+
compilerArguments, nil, {
4444
'/p:UseSharedCompilation=false'
4545
})
4646
}
@@ -50,44 +50,96 @@ function RegisterExtractorPack(id)
5050

5151
local windowsMatchers = {
5252
DotnetMatcherBuild,
53-
CreatePatternMatcher({'^dotnet%.exe$'}, MatchCompilerName, extractor, {
54-
prepend = {'--dotnetexec', '--cil'},
53+
CreatePatternMatcher({ '^csc.*%.exe$' }, MatchCompilerName, extractor, {
54+
prepend = { '--cil', '--compiler', '"${compiler}"' },
5555
order = ORDER_BEFORE
5656
}),
57-
CreatePatternMatcher({'^csc.*%.exe$'}, MatchCompilerName, extractor, {
58-
prepend = {'--compiler', '"${compiler}"', '--cil'},
59-
order = ORDER_BEFORE
60-
}),
61-
CreatePatternMatcher({'^fakes.*%.exe$', 'moles.*%.exe'},
62-
MatchCompilerName, nil, {trace = false})
57+
CreatePatternMatcher({ '^fakes.*%.exe$', 'moles.*%.exe' },
58+
MatchCompilerName, nil, { trace = false }),
59+
function(compilerName, compilerPath, compilerArguments, _languageId)
60+
-- handle cases like `dotnet.exe exec csc.dll <args>`
61+
if compilerName ~= 'dotnet.exe' then
62+
return nil
63+
end
64+
65+
local seenCompilerCall = false
66+
local argv = NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
67+
local extractorArgs = { '--cil', '--compiler' }
68+
for _, arg in ipairs(argv) do
69+
if arg:match('csc%.dll$') then
70+
seenCompilerCall = true
71+
end
72+
if seenCompilerCall then
73+
table.insert(extractorArgs, '"' .. arg .. '"')
74+
end
75+
end
76+
77+
if seenCompilerCall then
78+
return {
79+
order = ORDER_BEFORE,
80+
invocation = {
81+
path = AbsolutifyExtractorPath(id, extractor),
82+
arguments = {
83+
commandLineString = table.concat(extractorArgs, " ")
84+
}
85+
}
86+
}
87+
end
88+
return nil
89+
end
6390
}
6491
local posixMatchers = {
6592
DotnetMatcherBuild,
66-
CreatePatternMatcher({'^mono', '^dotnet$'}, MatchCompilerName,
67-
extractor, {
68-
prepend = {'--dotnetexec', '--cil'},
69-
order = ORDER_BEFORE
70-
}),
71-
CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName,
72-
extractor, {
73-
prepend = {'--compiler', '"${compiler}"', '--cil'},
93+
CreatePatternMatcher({ '^mcs%.exe$', '^csc%.exe$' }, MatchCompilerName,
94+
extractor, {
95+
prepend = { '--cil', '--compiler', '"${compiler}"' },
7496
order = ORDER_BEFORE
7597
}), function(compilerName, compilerPath, compilerArguments, _languageId)
7698
if MatchCompilerName('^msbuild$', compilerName, compilerPath,
77-
compilerArguments) or
99+
compilerArguments) or
78100
MatchCompilerName('^xbuild$', compilerName, compilerPath,
79-
compilerArguments) then
101+
compilerArguments) then
80102
return {
81103
order = ORDER_REPLACE,
82104
invocation = BuildExtractorInvocation(id, compilerPath,
83-
compilerPath,
84-
compilerArguments,
85-
nil, {
105+
compilerPath,
106+
compilerArguments,
107+
nil, {
86108
'/p:UseSharedCompilation=false'
87109
})
88110

89111
}
90112
end
113+
end, function(compilerName, compilerPath, compilerArguments, _languageId)
114+
-- handle cases like `dotnet exec csc.dll <args>` and `mono(-sgen64) csc.exe <args>`
115+
if compilerName ~= 'dotnet' and not compilerName:match('^mono') then
116+
return nil
117+
end
118+
119+
local seenCompilerCall = false
120+
local argv = compilerArguments.argv
121+
local extractorArgs = { '--cil', '--compiler' }
122+
for _, arg in ipairs(argv) do
123+
if arg:match('csc%.dll$') or arg:match('csc%.exe$') or arg:match('mcs%.exe$') then
124+
seenCompilerCall = true
125+
end
126+
if seenCompilerCall then
127+
table.insert(extractorArgs, arg)
128+
end
129+
end
130+
131+
if seenCompilerCall then
132+
return {
133+
order = ORDER_BEFORE,
134+
invocation = {
135+
path = AbsolutifyExtractorPath(id, extractor),
136+
arguments = {
137+
argv = extractorArgs
138+
}
139+
}
140+
}
141+
end
142+
return nil
91143
end
92144
}
93145
if OperatingSystem == 'windows' then
@@ -99,4 +151,4 @@ end
99151

100152
-- Return a list of minimum supported versions of the configuration file format
101153
-- return one entry per supported major version.
102-
function GetCompatibleVersions() return {'1.0.0'} end
154+
function GetCompatibleVersions() return { '1.0.0' } end

0 commit comments

Comments
 (0)