adding my changes to madanm-changes branch

This commit is contained in:
Madan Musuvathi 2016-09-22 10:00:03 -07:00
Родитель 92ef8aed06
Коммит 2131b3bf15
6 изменённых файлов: 446 добавлений и 258 удалений

Просмотреть файл

@ -15,63 +15,108 @@ namespace AnalysisClient
static void Main(string[] args)
{
if (Directory.Exists(args[0]))
{
AnalyzeAllJobsInDirectory(args);
return;
}
var inputDll = args[0];
var outputPath = args[1];
var logPath = args[2];
AnalyzeScopeScript(args);
AnalysisStats.PrintStats(System.Console.Out);
// AnalysisStats.PrintStats(System.Console.Out);
}
public static void AnalyzeAllJobsInDirectory(string[] args)
{
var inputDir = args[0];
// enumerate all GUIDs in this directory
var inputDlls = from dir in Directory.EnumerateDirectories(inputDir)
let scopeCodeGenFile = Path.Combine(dir, "__ScopeCodeGen__.dll")
where File.Exists(scopeCodeGenFile)
select scopeCodeGenFile;
Parallel.ForEach(inputDlls, new ParallelOptions { MaxDegreeOfParallelism = 10 },
inputDll =>
{
var process = new Process();
process.StartInfo = new ProcessStartInfo(Process.GetCurrentProcess().MainModule.FileName, String.Join(" ", new string[] { inputDll, args[1] }));
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
if(!process.WaitForExit(1000 * 60 * 10))
{
System.Console.WriteLine("{0} timed out", inputDll);
process.Kill();
}
}
);
}
public static void AnalyzeScopeScript(string[] args)
{
Console.Error.WriteLine("Analyzing {0}", args[0]);
var inputDll = args[0];
var outputFolder = args[1];
var tempPath = outputFolder;
var interproc = false;
var tempPath = outputFolder;
var dllToAnalyze = inputDll;
var folder = Path.GetDirectoryName(dllToAnalyze);
string[] directories = folder.Split(Path.DirectorySeparatorChar);
var logPath = Path.Combine(tempPath, directories.Last()) + "_" + Path.ChangeExtension(Path.GetFileName(dllToAnalyze), ".log");
var outputStream = File.CreateText(logPath);
var outputSummaryFile = Path.Combine(tempPath, "summary.txt");
//var referencesPath = Directory.GetFiles(folder, "*.dll", SearchOption.TopDirectoryOnly).Where(fp => Path.GetFileName(fp) != inputDllName).ToList();
//referencesPath.AddRange(Directory.GetFiles(folder, "*.exe", SearchOption.TopDirectoryOnly));
//var logPath = Path.Combine(tempPath, directories.Last()) + "_" + Path.ChangeExtension(Path.GetFileName(dllToAnalyze), ".log");
//var outputStream = File.CreateText(logPath);
var outputPath = Path.Combine(outputFolder, directories.Last()) + "_" + Path.ChangeExtension(Path.GetFileName(dllToAnalyze), ".sarif");
System.Console.WriteLine("=========================================================================");
System.Console.WriteLine("Folder #{0}", AnalysisStats.TotalNumberFolders);
System.Console.WriteLine("Analyzing {0}", dllToAnalyze);
outputStream.WriteLine("Folder #{0}", AnalysisStats.TotalNumberFolders);
outputStream.WriteLine("===========================================================================");
outputStream.WriteLine("Analyzing {0}", dllToAnalyze);
var output = ScopeProgramAnalysis.ScopeProgramAnalysis.AnalyzeDll(inputDll, ScopeProgramAnalysis.ScopeProgramAnalysis.ScopeMethodKind.All);
List<string> ret = new List<string>();
ScopeProgramAnalysis.ScopeProgramAnalysis.AnalyzeDllAndWriteLog(dllToAnalyze, outputPath, ScopeProgramAnalysis.ScopeProgramAnalysis.ScopeMethodKind.All, true, interproc, outputStream);
if (AnalysisStats.AnalysisReasons.Any())
if (output == null)
{
outputStream.WriteLine("Analysis reasons for {0}", dllToAnalyze);
AnalysisStats.WriteAnalysisReasons(outputStream);
ret.Add(String.Join("\t", new string[] {
inputDll,
ScopeProgramAnalysis.AnalysisStats.StatsAsString(),
"__ERROR__" }));
}
else
{
ScopeProgramAnalysis.ScopeProgramAnalysis.WriteSarifOutput(output, outputPath);
var depStream = ScopeProgramAnalysis.ScopeProgramAnalysis.ExtractDependencyStats(output);
foreach (var x in depStream)
{
var processorName = x.Item1;
ScopeProgramAnalysis.ScopeProgramAnalysis.DependencyStats stats = x.Item2;
ret.Add(String.Join("\t", new string[] {
inputDll,
ScopeProgramAnalysis.AnalysisStats.StatsAsString(),
processorName,
stats.InputHasTop.ToString(),
stats.OutputHasTop.ToString(),
stats.TopHappened.ToString(),
stats.PassThroughColumns.Count.ToString(),
String.Join(",",stats.PassThroughColumns),
stats.UnreadInputs.Count.ToString(),
String.Join(",", stats.UnreadInputs)
}));
}
}
var retStr = String.Join("\n", ret) + "\n";
using (var mutex = new System.Threading.Mutex(false, "ScopeDependencyAnalysis_OutputSummaryMutex"))
{
mutex.WaitOne();
File.AppendAllText(outputSummaryFile, retStr);
mutex.ReleaseMutex();
}
outputStream.WriteLine("===========================================================================");
outputStream.Flush();
System.Console.WriteLine("=========================================================================");
AnalysisStats.PrintStats(outputStream);
outputStream.WriteLine("End.");
outputStream.Flush();
System.Console.WriteLine("Done!");
}
}
}

Просмотреть файл

@ -41,13 +41,20 @@ namespace ScopeProgramAnalysis
public static int TotalDllsFound { get; set; }
public static int TotalDllsFailedToLoad{ get; set; }
public static int NumUDOs { get; set; }
public static int NumCandidateClosures { get; set; }
public static int TotalMethods { get; set; }
public static int TotalProducers { get; set; }
public static int TotalMethodsNotFound { get; set; }
public static HashSet<string> MethodsNotFound = new HashSet<string>();
public static int TotalofFrameworkErrors { get; set; }
public static int TotalofPTAErrors{ get; set; }
public static int TotalofDepAnalysisErrors { get; set; }
public static HashSet<string> EmptyClasses = new HashSet<string>();
public static HashSet<string> EmptyCandidateClosures = new HashSet<string>();
public static string CurrentScript = "NoSet";
@ -69,7 +76,7 @@ namespace ScopeProgramAnalysis
output.WriteLine("Dlls Fail to Load: {0}", TotalDllsFailedToLoad);
output.WriteLine("Showing the first 10...: {0}", String.Join(", ", DllThatFailedToLoad.Take(Math.Min(10,DllThatFailedToLoad.Count()))));
output.WriteLine("Total Methods Resolved: {0}", TotalMethods);
output.WriteLine("Total Methods Unsolved: {0}", TotalMethodsNotFound);
output.WriteLine("Total Methods Unsolved: {0}", MethodsNotFound.Count);
//output.WriteLine("Total Producers: {0}", TotalProducers);
output.WriteLine("Total Depencency Analysis errors: {0}", TotalofDepAnalysisErrors);
output.WriteLine("Total PTA errors: {0}", TotalofPTAErrors);
@ -79,6 +86,18 @@ namespace ScopeProgramAnalysis
}
public static string StatsAsString(string sep = "\t")
{
return String.Join(sep,
NumUDOs.ToString(),
TotalofDepAnalysisErrors.ToString(),
TotalofFrameworkErrors.ToString(),
TotalofPTAErrors.ToString(),
String.Join(",", MethodsNotFound.ToList()),
String.Join(",", EmptyClasses.ToList()),
String.Join(",", EmptyCandidateClosures.ToList()),
String.Join(",", DllThatFailedToLoad.ToList()));
}
public static void WriteAnalysisReasons(TextWriter output)
{
foreach(var entry in AnalysisReasons)

Просмотреть файл

@ -187,7 +187,7 @@ namespace ScopeProgramAnalysis
//resultDepAnalysis = dependencyAnalysis.Analyze();
var node = cfg.Exit;
System.Console.Out.WriteLine("At {0}\nBefore {1}\nAfter {2}\n", node.Id, resultDepAnalysis[node.Id].Input, resultDepAnalysis[node.Id].Output);
//System.Console.Out.WriteLine("At {0}\nBefore {1}\nAfter {2}\n", node.Id, resultDepAnalysis[node.Id].Input, resultDepAnalysis[node.Id].Output);
this.InputColumns = dependencyAnalysis.InputColumns;
this.OutputColumns = dependencyAnalysis.OutputColumns;

Просмотреть файл

@ -1,174 +1,174 @@
using CCIProvider;
using Model;
using Model.Types;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ScopeProgramAnalysis.Framework
{
class MyLoader : Loader
{
private string assemblyFolder;
private string assemblyParentFolder;
private HashSet<IAssemblyReference> failedAssemblies;
private Assembly mainAssemably;
public MyLoader(Host host) : base(host)
{
this.failedAssemblies = new HashSet<IAssemblyReference>();
}
public Assembly LoadMainAssembly(string fileName)
{
this.assemblyFolder = Path.GetDirectoryName(fileName);
this.assemblyParentFolder = Directory.GetParent(Path.GetDirectoryName(fileName)).FullName;
cciHost.AddLibPath(assemblyFolder);
cciHost.AddLibPath(assemblyParentFolder);
this.mainAssemably = base.LoadAssembly(fileName);
return this.mainAssemably;
}
public Assembly TryToLoadReferencedAssembly(IAssemblyReference reference)
{
var assembly = this.ourHost.Assemblies.SingleOrDefault(a => a.MatchReference(reference));
if (assembly == null && !failedAssemblies.Contains(reference))
{
try
{
AnalysisStats.TotalDllsFound++;
assembly = TryToLoadAssembly(reference.Name);
}
catch (Exception e)
{
System.Console.WriteLine("We could not solve this reference: {0}", reference.Name);
failedAssemblies.Add(reference);
throw e;
}
}
return assembly;
}
private Assembly TryToLoadAssembly(string assemblyReferenceName)
{
//if(assemblyReferenceName=="mscorlib")
//{
// return LoadCoreAssembly();
//}
var extensions = new string[] { ".dll", ".exe" };
var referencePath = "";
foreach (var extension in extensions)
{
referencePath = Path.Combine(assemblyFolder, assemblyReferenceName) + extension;
if (File.Exists(referencePath))
break;
referencePath = Path.Combine(assemblyParentFolder, assemblyReferenceName) + extension;
if (File.Exists(referencePath))
break;
}
//var cciAssemblyFromReference = cciHost.LoadUnitFrom(referencePath) as Cci.IModule;
//// var cciAssemblyFromReference = cciHost.LoadUnit(assemblyReference.AssemblyIdentity) as Cci.IAssembly;
//return cciAssemblyFromReference;
return LoadAssembly(referencePath);
}
//public Assembly LoadAssemblyAndReferences(string fileName)
//{
// var module = cciHost.LoadUnitFrom(fileName) as Cci.IModule;
// if (module == null || module == Cci.Dummy.Module || module == Cci.Dummy.Assembly)
// throw new Exception("The input is not a valid CLR module or assembly.");
// var pdbFileName = Path.ChangeExtension(fileName, "pdb");
// Cci.PdbReader pdbReader = null;
// if (File.Exists(pdbFileName))
// {
// using (var pdbStream = File.OpenRead(pdbFileName))
// {
// pdbReader = new Cci.PdbReader(pdbStream, cciHost);
// }
// }
// var assembly = this.ExtractAssembly(module, pdbReader);
// if (pdbReader != null)
// {
// pdbReader.Dispose();
// }
// ourHost.Assemblies.Add(assembly);
// this.assemblyFolder = Path.GetDirectoryName(fileName);
// this.assemblyParentFolder = Directory.GetParent(Path.GetDirectoryName(fileName)).FullName;
// cciHost.AddLibPath(assemblyFolder);
// cciHost.AddLibPath(assemblyParentFolder);
// foreach (var assemblyReference in module.AssemblyReferences)
// {
// try
// {
// Cci.IModule cciAssemblyFromReference = TryToLoadCCIAssembly(assemblyReference);
// if (cciAssemblyFromReference == null || cciAssemblyFromReference == Cci.Dummy.Assembly)
// throw new Exception("The input is not a valid CLR module or assembly.");
// var pdbLocation = cciAssemblyFromReference.DebugInformationLocation;
// if (File.Exists(pdbFileName))
// {
// using (var pdbStream = File.OpenRead(pdbFileName))
// {
// pdbReader = new Cci.PdbReader(pdbStream, cciHost);
// }
// }
// var assemblyFromRef = this.ExtractAssembly(cciAssemblyFromReference, pdbReader);
// ourHost.Assemblies.Add(assemblyFromRef);
// if (pdbReader != null)
// {
// pdbReader.Dispose();
// }
// }
// catch (Exception e)
// {
// }
// }
// return assembly;
//}
}
class MyHost : Host
{
public MyLoader Loader { get; set; }
public override ITypeDefinition ResolveReference(IBasicType typeToResolve)
{
var resolvedType = base.ResolveReference(typeToResolve);
if (resolvedType == null)
{
try
{
Loader.TryToLoadReferencedAssembly(typeToResolve.ContainingAssembly);
resolvedType = base.ResolveReference(typeToResolve);
}
catch (Exception e)
{
AnalysisStats.DllThatFailedToLoad.Add(typeToResolve.ContainingAssembly.Name);
AnalysisStats.TotalDllsFailedToLoad++;
System.Diagnostics.Debug.WriteLine("Failed to load {0}: {1}", typeToResolve.ContainingAssembly.Name, e.Message);
}
}
return resolvedType;
}
public override ITypeMemberDefinition ResolveReference(ITypeMemberReference member)
{
return base.ResolveReference(member);
}
}
}
using CCIProvider;
using Model;
using Model.Types;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ScopeProgramAnalysis.Framework
{
class MyLoader : Loader
{
private string assemblyFolder;
private string assemblyParentFolder;
private HashSet<IAssemblyReference> failedAssemblies;
private Assembly mainAssemably;
public MyLoader(Host host) : base(host)
{
this.failedAssemblies = new HashSet<IAssemblyReference>();
}
public Assembly LoadMainAssembly(string fileName)
{
this.assemblyFolder = Path.GetDirectoryName(fileName);
this.assemblyParentFolder = Directory.GetParent(Path.GetDirectoryName(fileName)).FullName;
cciHost.AddLibPath(assemblyFolder);
cciHost.AddLibPath(assemblyParentFolder);
this.mainAssemably = base.LoadAssembly(fileName);
return this.mainAssemably;
}
public Assembly TryToLoadReferencedAssembly(IAssemblyReference reference)
{
var assembly = this.ourHost.Assemblies.SingleOrDefault(a => a.MatchReference(reference));
if (assembly == null && !failedAssemblies.Contains(reference))
{
try
{
AnalysisStats.TotalDllsFound++;
assembly = TryToLoadAssembly(reference.Name);
}
catch (Exception e)
{
// System.Console.WriteLine("We could not solve this reference: {0}", reference.Name);
failedAssemblies.Add(reference);
throw;
}
}
return assembly;
}
private Assembly TryToLoadAssembly(string assemblyReferenceName)
{
//if(assemblyReferenceName=="mscorlib")
//{
// return LoadCoreAssembly();
//}
var extensions = new string[] { ".dll", ".exe" };
var referencePath = "";
foreach (var extension in extensions)
{
referencePath = Path.Combine(assemblyFolder, assemblyReferenceName) + extension;
if (File.Exists(referencePath))
break;
referencePath = Path.Combine(assemblyParentFolder, assemblyReferenceName) + extension;
if (File.Exists(referencePath))
break;
}
//var cciAssemblyFromReference = cciHost.LoadUnitFrom(referencePath) as Cci.IModule;
//// var cciAssemblyFromReference = cciHost.LoadUnit(assemblyReference.AssemblyIdentity) as Cci.IAssembly;
//return cciAssemblyFromReference;
return LoadAssembly(referencePath);
}
//public Assembly LoadAssemblyAndReferences(string fileName)
//{
// var module = cciHost.LoadUnitFrom(fileName) as Cci.IModule;
// if (module == null || module == Cci.Dummy.Module || module == Cci.Dummy.Assembly)
// throw new Exception("The input is not a valid CLR module or assembly.");
// var pdbFileName = Path.ChangeExtension(fileName, "pdb");
// Cci.PdbReader pdbReader = null;
// if (File.Exists(pdbFileName))
// {
// using (var pdbStream = File.OpenRead(pdbFileName))
// {
// pdbReader = new Cci.PdbReader(pdbStream, cciHost);
// }
// }
// var assembly = this.ExtractAssembly(module, pdbReader);
// if (pdbReader != null)
// {
// pdbReader.Dispose();
// }
// ourHost.Assemblies.Add(assembly);
// this.assemblyFolder = Path.GetDirectoryName(fileName);
// this.assemblyParentFolder = Directory.GetParent(Path.GetDirectoryName(fileName)).FullName;
// cciHost.AddLibPath(assemblyFolder);
// cciHost.AddLibPath(assemblyParentFolder);
// foreach (var assemblyReference in module.AssemblyReferences)
// {
// try
// {
// Cci.IModule cciAssemblyFromReference = TryToLoadCCIAssembly(assemblyReference);
// if (cciAssemblyFromReference == null || cciAssemblyFromReference == Cci.Dummy.Assembly)
// throw new Exception("The input is not a valid CLR module or assembly.");
// var pdbLocation = cciAssemblyFromReference.DebugInformationLocation;
// if (File.Exists(pdbFileName))
// {
// using (var pdbStream = File.OpenRead(pdbFileName))
// {
// pdbReader = new Cci.PdbReader(pdbStream, cciHost);
// }
// }
// var assemblyFromRef = this.ExtractAssembly(cciAssemblyFromReference, pdbReader);
// ourHost.Assemblies.Add(assemblyFromRef);
// if (pdbReader != null)
// {
// pdbReader.Dispose();
// }
// }
// catch (Exception e)
// {
// }
// }
// return assembly;
//}
}
class MyHost : Host
{
public MyLoader Loader { get; set; }
public override ITypeDefinition ResolveReference(IBasicType typeToResolve)
{
var resolvedType = base.ResolveReference(typeToResolve);
if (resolvedType == null)
{
try
{
Loader.TryToLoadReferencedAssembly(typeToResolve.ContainingAssembly);
resolvedType = base.ResolveReference(typeToResolve);
}
catch (Exception e)
{
AnalysisStats.DllThatFailedToLoad.Add(typeToResolve.ContainingAssembly.Name);
AnalysisStats.TotalDllsFailedToLoad++;
System.Diagnostics.Debug.WriteLine("Failed to load {0}: {1}", typeToResolve.ContainingAssembly.Name, e.Message);
}
}
return resolvedType;
}
public override ITypeMemberDefinition ResolveReference(ITypeMemberReference member)
{
return base.ResolveReference(member);
}
}
}

Просмотреть файл

@ -470,8 +470,8 @@ namespace Backend.Analyses
// ptg.PointsTo(node, access.Field, ptg.Null);
if (!reachable)
{
System.Console.WriteLine("In {0}:{1:X4}. Variable {2} field {3} has no object to load and {2} is not a parameter.",
this.method.ToSignatureString(), offset, instance, field);
//System.Console.WriteLine("In {0}:{1:X4}. Variable {2} field {3} has no object to load and {2} is not a parameter.",
// this.method.ToSignatureString(), offset, instance, field);
if(field.Name=="[]")
{
targets.AddRange(nodes);

Просмотреть файл

@ -151,7 +151,7 @@ namespace ScopeProgramAnalysis
input = @"\\madanm2\parasail2\TFS\parasail\ScopeSurvey\AutoDownloader\bin\Debug\02c4581e-781a-4798-8875-162b4d740b5f\__ScopeCodeGen__.dll";
// Can not find methods in the factory
input = @"\\madanm2\parasail2\TFS\parasail\ScopeSurvey\AutoDownloader\bin\Debug\0e4ca5d2-3478-431f-a4ad-f0b256780daf\__ScopeCodeGen__.dll";
// input = @"\\madanm2\parasail2\TFS\parasail\ScopeSurvey\AutoDownloader\bin\Debug\0e4ca5d2-3478-431f-a4ad-f0b256780daf\__ScopeCodeGen__.dll";
string[] directories = Path.GetDirectoryName(input).Split(Path.DirectorySeparatorChar);
@ -195,23 +195,23 @@ namespace ScopeProgramAnalysis
Console.Write("Processor: {0}. ", processor.Attribute("className").Value);
var inputSchema = ParseColumns(processor.Descendants("input").FirstOrDefault().Attribute("schema").Value);
}
private static IEnumerable<Column> ParseColumns(string schema)
{
// schema looks like: "JobGUID:string,SubmitTime:DateTime?,NewColumn:string"
var schemaList = schema.Split(',');
for(int i=0;i<schemaList.Count(); i++)
for (int i = 0; i < schemaList.Count(); i++)
{
if(schemaList[i].Contains("<") && i<schemaList.Count() && schemaList[i+1].Contains(">"))
if (schemaList[i].Contains("<") && i < schemaList.Count()-1 && schemaList[i + 1].Contains(">"))
{
schemaList[i] += schemaList[i + 1];
schemaList[i + 1] = "";
i++;
}
}
return schemaList.Where( elem => !String.IsNullOrEmpty(elem)).Select((c, i) => { var a = c.Split(':'); return new Column(a[0], new RangeDomain(i), a[1]); });
return schemaList.Where(elem => !String.IsNullOrEmpty(elem)).Select((c, i) => { var a = c.Split(':'); return new Column(a[0], new RangeDomain(i), a[1]); });
//return schema
// .Split(',')
@ -219,9 +219,9 @@ namespace ScopeProgramAnalysis
}
public static SarifLog AnalyzeDll(string inputPath, ScopeMethodKind kind,
public static SarifLog AnalyzeDll(string inputPath, ScopeMethodKind kind,
bool useScopeFactory = true, bool interProc = false, StreamWriter outputStream = null)
bool useScopeFactory = true, bool interProc = false, StreamWriter outputStream = null)
{
// Determine whether to use Interproc analysis
AnalysisOptions.DoInterProcAnalysis = interProc;
@ -274,7 +274,7 @@ namespace ScopeProgramAnalysis
scopeMethodPairs = program.ObtainScopeMethodsToAnalyze();
if (!scopeMethodPairs.Any())
{
if(outputStream!=null)
if (outputStream != null)
outputStream.WriteLine("Failed to obtain methods from the ScopeFactory. ");
System.Console.WriteLine("Failed to obtain methods from the ScopeFactory.");
@ -296,7 +296,8 @@ namespace ScopeProgramAnalysis
if (useScopeFactory)
{
allSchemas = program.ReadSchemasFromXML(inputPath);
} else
}
else
{
allSchemas = program.ReadSchemasFromXML2(inputPath);
}
@ -308,7 +309,7 @@ namespace ScopeProgramAnalysis
var entryMethodDef = methodPair.Item1;
var moveNextMethod = methodPair.Item2;
var getEnumMethod = methodPair.Item3;
System.Console.WriteLine("Method {0} on class {1}", moveNextMethod.Name, moveNextMethod.ContainingType.FullPathName());
//System.Console.WriteLine("Method {0} on class {1}", moveNextMethod.Name, moveNextMethod.ContainingType.FullPathName());
Schema inputSchema = null;
Schema outputSchema = null;
@ -327,7 +328,7 @@ namespace ScopeProgramAnalysis
var dependencyAnalysis = new SongTaoDependencyAnalysis(host, program.interprocAnalysisManager, moveNextMethod, entryMethodDef, getEnumMethod);
var depAnalysisResult = dependencyAnalysis.AnalyzeMoveNextMethod();
WriteResultToSarifLog(inputPath, outputStream, log, moveNextMethod, depAnalysisResult, dependencyAnalysis, program.factoryReducerMap);
WriteResultToSarifLog(inputPath, outputStream, log, moveNextMethod, depAnalysisResult, dependencyAnalysis, program.factoryReducerMap);
InputSchema = null;
OutputSchema = null;
@ -358,9 +359,115 @@ namespace ScopeProgramAnalysis
WriteSarifOutput(log, outputPath);
}
public class DependencyStats
{
public List<Tuple<string, string>> PassThroughColumns = new List<Tuple<string, string>>();
public List<string> UnreadInputs = new List<string>();
public bool TopHappened;
public bool OutputHasTop;
public bool InputHasTop;
public int ColumnsSchemaInput;
public int ColumnsSchemaOutput;
private static void WriteResultToSarifLog(string inputPath, StreamWriter outputStream, SarifLog log, MethodDefinition moveNextMethod, DependencyPTGDomain depAnalysisResult,
SongTaoDependencyAnalysis dependencyAnalysis, IDictionary<string, ClassDefinition> processorMap)
}
public static IEnumerable<Tuple<string, DependencyStats>> ExtractDependencyStats(SarifLog log)
{
foreach (var run in log.Runs)
{
var tool = run.Tool.Name;
if (tool != "ScopeProgramAnalysis") continue;
var splitId = run.Id.Split('|');
var processNumber = "0";
var processorName = "";
if (splitId.Length == 2)
{
processorName = splitId[0];
processNumber = splitId[1];
}
else
{
processorName = run.Id;
}
var ret = new DependencyStats();
var visitedColumns = new HashSet<string>();
var inputColumnsRead = new HashSet<string>();
foreach (var result in run.Results)
{
if (result.Id == "SingleColumn")
{
var columnProperty = result.GetProperty("column");
if (!columnProperty.StartsWith("Col(")) continue;
var columnName = columnProperty.Split(',')[1].Trim('"', ')');
if (columnName == "_All_")
{
// ignore this for now because it is more complicated
continue;
}
if (columnName == "_TOP_")
{
ret.TopHappened = true;
}
if (visitedColumns.Contains(columnName))
continue;
visitedColumns.Add(columnName);
var dataDependencies = result.GetProperty<List<string>>("data depends");
if (dataDependencies.Count == 1)
{
var inputColumn = dataDependencies[0];
if (!inputColumn.StartsWith("Col(Input"))
{
// then it is dependent on only one thing, but that thing is not a column.
continue;
}
if (inputColumn.Contains("TOP"))
{
// a pass through column cannot depend on TOP
continue;
}
// then it is a pass-through column
var inputColumnName = inputColumn.Split(',')[1].Trim('"', ')');
ret.PassThroughColumns.Add(Tuple.Create(columnName, inputColumnName));
}
}
else if (result.Id == "Summary")
{
// Do nothing
var columnProperty = result.GetProperty<List<string>>("Inputs");
var totalInputColumns = columnProperty.Count;
ret.InputHasTop = columnProperty.Contains("Col(Input,_TOP_)");
var inputColumns = columnProperty.Select(x => x.Split(',')[1].Trim('"', ')'));
columnProperty = result.GetProperty<List<string>>("Outputs");
var totalOutputColumns = columnProperty.Count;
ret.OutputHasTop = columnProperty.Contains("Col(Output,_TOP_)");
columnProperty = result.GetProperty<List<string>>("SchemaInputs");
ret.ColumnsSchemaInput = columnProperty.Count;
if (!ret.InputHasTop)
{
ret.UnreadInputs = columnProperty.Where(schemaInput => !inputColumns.Contains(schemaInput)).ToList();
}
columnProperty = result.GetProperty<List<string>>("SchemaOutputs");
ret.ColumnsSchemaOutput = columnProperty.Count;
yield return Tuple.Create(processorName, ret);
ret = new DependencyStats();
}
}
}
}
private static void WriteResultToSarifLog(string inputPath, StreamWriter outputStream, SarifLog log, MethodDefinition moveNextMethod, DependencyPTGDomain depAnalysisResult,
SongTaoDependencyAnalysis dependencyAnalysis, IDictionary<string, ClassDefinition> processorMap)
{
var results = new List<Result>();
@ -515,10 +622,10 @@ namespace ScopeProgramAnalysis
results.Add(result);
var resultEmpty = new Result();
resultEmpty.Id = "Summary";
resultEmpty.SetProperty("Inputs", "_TOP_");
resultEmpty.SetProperty("Outputs", "_TOP_");
resultEmpty.SetProperty("SchemaInputs", "_TOP_");
resultEmpty.SetProperty("SchemaOutputs", "_TOP_");
resultEmpty.SetProperty("Inputs", new List<string>() { "_TOP_" });
resultEmpty.SetProperty("Outputs", new List<string>() { "_TOP_" });
resultEmpty.SetProperty("SchemaInputs", new List<string>() { "_TOP_" });
resultEmpty.SetProperty("SchemaOutputs", new List<string>() { "_TOP_" });
results.Add(resultEmpty);
}
@ -560,7 +667,8 @@ namespace ScopeProgramAnalysis
}
catch (Exception e)
{
System.Console.WriteLine("Cannot load {0}:{1}", referenceFileName, e.Message);
AnalysisStats.DllThatFailedToLoad.Add(referenceFileName);
AnalysisStats.TotalDllsFailedToLoad++;
}
}
}
@ -600,44 +708,60 @@ namespace ScopeProgramAnalysis
if (isCompilerGenerated)
continue;
AnalysisStats.NumUDOs++;
ClassDefinition resolvedEntryClass = null;
try
{
resolvedEntryClass = host.ResolveReference(reducerClass) as ClassDefinition;
if (resolvedEntryClass != null)
if (resolvedEntryClass == null)
{
if (processorsToAnalyze.Contains(resolvedEntryClass))
continue;
AnalysisStats.MethodsNotFound.Add(reducerClass.Name);
continue;
processorsToAnalyze.Add(resolvedEntryClass);
var candidateClousures = resolvedEntryClass.Types.OfType<ClassDefinition>()
.Where(c => this.ClousureFilters.Any(filter => c.Name.StartsWith(filter)));
foreach (var candidateClousure in candidateClousures)
{
var moveNextMethods = candidateClousure.Methods
.Where(md => md.Body != null && md.Name.Equals(this.MethodUnderAnalysisName));
var getEnumMethods = candidateClousure.Methods
.Where(m => m.Name == ScopeAnalysisConstants.SCOPE_ROW_ENUMERATOR_METHOD);
foreach (var moveNextMethod in moveNextMethods)
{
var entryMethod = resolvedEntryClass.Methods.Where(m => this.EntryMethods.Contains(m.Name)).Single();
var getEnumeratorMethod = getEnumMethods.Single();
scopeMethodPairsToAnalyze.Add(new Tuple<MethodDefinition, MethodDefinition, MethodDefinition>(entryMethod, moveNextMethod, getEnumeratorMethod));
// TODO: Hack for reuse. Needs refactor
if (factoryMethod != null)
{
var processID = factoryMethod.Name.Substring(factoryMethod.Name.IndexOf("Process_"));
this.factoryReducerMap.Add(processID, entryMethod.ContainingType as ClassDefinition);
}
}
}
}
else
if (processorsToAnalyze.Contains(resolvedEntryClass))
continue;
processorsToAnalyze.Add(resolvedEntryClass);
var typeDefs = resolvedEntryClass.Types.OfType<ClassDefinition>();
if(!typeDefs.Any())
{
AnalysisStats.TotalMethodsNotFound++;
AnalysisStats.EmptyClasses.Add(resolvedEntryClass.Name);
continue;
}
var candidateClousures = typeDefs.Where(c => this.ClousureFilters.Any(filter => c.Name.StartsWith(filter)));
if (!candidateClousures.Any())
{
AnalysisStats.EmptyCandidateClosures.Add(resolvedEntryClass.Name);
continue;
}
foreach (var candidateClousure in candidateClousures)
{
var moveNextMethods = candidateClousure.Methods
.Where(md => md.Body != null && md.Name.Equals(this.MethodUnderAnalysisName));
var getEnumMethods = candidateClousure.Methods
.Where(m => m.Name == ScopeAnalysisConstants.SCOPE_ROW_ENUMERATOR_METHOD);
foreach (var moveNextMethod in moveNextMethods)
{
var entryMethod = resolvedEntryClass.Methods.Where(m => this.EntryMethods.Contains(m.Name)).Single();
var getEnumeratorMethod = getEnumMethods.Single();
scopeMethodPairsToAnalyze.Add(new Tuple<MethodDefinition, MethodDefinition, MethodDefinition>(entryMethod, moveNextMethod, getEnumeratorMethod));
// madanm: factoryMethod is guaranteed to be non nullp
//// TODO: Hack for reuse. Needs refactor
//if (factoryMethod != null)
//{
var processID = factoryMethod.Name.Substring(factoryMethod.Name.IndexOf("Process_"));
this.factoryReducerMap.Add(processID, entryMethod.ContainingType as ClassDefinition);
//}
}
}
}
catch (Exception e)