/// <summary> /// Updates the tasks. /// </summary> /// <param name="machineTrace">MachineActionTrace</param> void UpdateTasks(MachineActionTrace machineTrace) { int currentMachineVC = 0; foreach (MachineActionInfo info in machineTrace) { if (info.Type == MachineActionType.TaskMachineCreation) { //ThreadTrace matching = null; var matching = this.AllThreadTraces.Where(item => item.IsTask && item.TaskId == info.TaskId); if (matching.Count() == 0) { continue; } Node cn = new CActBegin(info.TaskMachineId.GetHashCode(), info.TaskId); ((CActBegin)cn).IsStart = true; cn.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn.VectorClock[info.TaskMachineId.GetHashCode()] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.TaskMachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn); foreach (var m in matching) { if (m.Accesses.Count > 0) { foreach (ActionInstr ins in m.Accesses) { ((CActBegin)cn).Addresses.Add(new MemAccess(ins.IsWrite, ins.Location, ins.ObjHandle, ins.Offset, ins.SrcLocation, info.TaskMachineId.GetHashCode())); } } } } } }
/// <summary> /// Starts the engine. /// </summary> public bool Start() { IO.PrintLine(". Searching for data races"); string directoryPath = Path.GetDirectoryName(this.Configuration.AssemblyToBeAnalyzed) + Path.DirectorySeparatorChar + "Output"; string runtimeTraceDirectoryPath = directoryPath + Path.DirectorySeparatorChar + "RuntimeTraces" + Path.DirectorySeparatorChar; string threadTraceDirectoryPath = directoryPath + Path.DirectorySeparatorChar + "ThreadTraces" + Path.DirectorySeparatorChar; if (this.Configuration.EnableProfiling) { this.Profiler.StartMeasuringExecutionTime(); } string[] fileEntries = Directory.GetFiles(threadTraceDirectoryPath, "*"); int NumberOfIterations = 0; foreach (string fileName in fileEntries) { string iterationStart = fileName.Substring(fileName.IndexOf("iteration_") + 10); string iterationNumber = iterationStart.Substring(0, iterationStart.IndexOf('_')); int currentIteration = Int32.Parse(iterationNumber); if (currentIteration > NumberOfIterations) { NumberOfIterations = currentIteration; } } string[] tfileEntries = Directory.GetFiles(threadTraceDirectoryPath, ("*_iteration_" + NumberOfIterations + "*")); foreach (string fileName in tfileEntries) { //Deserialize thread traces //Open the file written above and read values from it. Stream stream = File.Open(fileName, FileMode.Open); BinaryFormatter bformatter = new BinaryFormatter(); List <ThreadTrace> tt = (List <ThreadTrace>)bformatter.Deserialize(stream); for (int i = 0; i < tt.Count; i++) { this.AllThreadTraces.Add(tt[i]); } stream.Close(); } string[] mFileEntries = Directory.GetFiles(runtimeTraceDirectoryPath, ("*_iteration_" + NumberOfIterations + "*")); this.VcCount = mFileEntries.Count() + 5; //TODO: fix this foreach (string fileName in mFileEntries) { //chain decomposition string fileNumberStart = fileName.Substring(fileName.LastIndexOf('_') + 1); string fileNumber = fileNumberStart.Substring(0, fileNumberStart.IndexOf('.')); int tc = Int32.Parse(fileNumber); if (tc > this.VcCount) { this.VcCount = tc; } } this.VcCount = this.VcCount + 10; foreach (string fileName in mFileEntries) { MachineActionTrace machineTrace = null; using (FileStream stream = File.Open(fileName, FileMode.Open)) { DataContractSerializer serializer = new DataContractSerializer( typeof(MachineActionTrace)); machineTrace = serializer.ReadObject(stream) as MachineActionTrace; } this.UpdateTasks(machineTrace); this.UpdateGraph(machineTrace); } this.UpdateGraphCrossEdges(); if (this.Configuration.EnableProfiling) { this.Profiler.StopMeasuringExecutionTime(); IO.PrintLine("... Graph construction runtime: '" + this.Profiler.Results() + "' seconds."); } if (this.Configuration.EnableProfiling) { this.Profiler.StartMeasuringExecutionTime(); } //Console.WriteLine("before pruning: nodes = " + CGraph.VertexCount + "; edges = " + CGraph.EdgeCount); this.PruneGraph(); //Console.WriteLine("after pruning: nodes = " + CGraph.VertexCount + "; edges = " + CGraph.EdgeCount); if (this.Configuration.EnableProfiling) { this.Profiler.StopMeasuringExecutionTime(); IO.PrintLine("... Graph prune runtime: '" + this.Profiler.Results() + "' seconds."); } if (this.Configuration.EnableProfiling) { this.Profiler.StartMeasuringExecutionTime(); } this.UpdateVectorsT(); if (this.Configuration.EnableProfiling) { this.Profiler.StopMeasuringExecutionTime(); IO.PrintLine("... Topological sort runtime: '" + this.Profiler.Results() + "' seconds."); } if (this.Configuration.EnableProfiling) { this.Profiler.StartMeasuringExecutionTime(); } bool foundBug = this.DetectRacesFast(); if (this.Configuration.EnableProfiling) { this.Profiler.StopMeasuringExecutionTime(); IO.PrintLine("... Race detection runtime: '" + this.Profiler.Results() + "' seconds."); } this.CGraph.Clear(); this.AllThreadTraces.Clear(); return(foundBug); }
/// <summary> /// Updates the graph. /// </summary> /// <param name="machineTrace">MachineActionTrace</param> void UpdateGraph(MachineActionTrace machineTrace) { int currentMachineVC = 0; Node cLatestAction = null; foreach (MachineActionInfo info in machineTrace) { if (info.Type != MachineActionType.SendAction && (info.ActionId != 0) && !(info.Type == MachineActionType.TaskMachineCreation)) { ThreadTrace matching = null; try { matching = this.AllThreadTraces.Where(item => item.MachineId == info.MachineId && item.ActionId == info.ActionId).Single(); } catch (Exception) { //TODO: check correctness //In case entry and exit functions not defined. //IO.PrintLine("Skipping entry/exit actions: " + mt.MachineId + " " + mt.ActionId + " " + mt.ActionName); continue; } Node cn = new CActBegin(matching.MachineId, matching.ActionName, matching.ActionId, info.EventName, info.EventId); if (matching.ActionId == 1) { ((CActBegin)cn).IsStart = true; } cn.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn); if (cLatestAction != null) { this.CGraph.AddEdge(new Edge(cLatestAction, cn)); } Node cLatest = cn; cLatestAction = cn; bool createNew = false; foreach (ActionInstr ins in matching.Accesses) { // User trace send event. Node cn1; if (createNew) { Node cnn = new CActBegin(matching.MachineId, matching.ActionName, matching.ActionId, info.EventName, info.EventId); cnn.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cnn.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cnn); cn = cnn; this.CGraph.AddEdge(new Edge(cLatest, cn)); createNew = false; cLatest = cn; } if (ins.IsSend) { MachineActionInfo machineSend = machineTrace.Where( item => item.MachineId == matching.MachineId && item.SendId == ins.SendId).Single(); cn1 = new SendEvent(machineSend.MachineId, machineSend.SendId, machineSend.TargetMachineId, machineSend.SendEventName, machineSend.EventId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace create machine. else if (ins.IsCreate) { cn1 = new CreateMachine(ins.CreateMachineId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace task creation. else if (ins.IsTask) { cn1 = new CreateTask(ins.TaskId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace reads/writes. else { ((CActBegin)cn).Addresses.Add(new MemAccess(ins.IsWrite, ins.Location, ins.ObjHandle, ins.Offset, ins.SrcLocation, info.MachineId)); cn1 = cn; } cLatest = cn1; cLatestAction = cn1; } } } }
/// <summary> /// Updates the tasks. /// </summary> /// <param name="machineTrace">MachineActionTrace</param> void UpdateTasks(MachineActionTrace machineTrace) { //int currentMachineVC = 0; //foreach (MachineActionInfo info in machineTrace) //{ // if (info.isTaskMachine) // { // //ThreadTrace matching = null; // var matching = this.AllThreadTraces.Where(item => item.IsTask && item.TaskId == mt.TaskId); // if (matching.Count() == 0) // continue; // Node cn = new CActBegin(info.MachineId, info.TaskId); // ((CActBegin)cn).IsStart = true; // cn.VectorClock = new int[this.VcCount]; // currentMachineVC++; // try // { // cn.VectorClock[info.MachineId] = currentMachineVC; // } // catch (Exception ex) // { // IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); // IO.PrintLine(ex); // Environment.Exit(Environment.ExitCode); // } // this.CGraph.AddVertex(cn); // foreach (var m in matching) // { // if (m.accesses.Count > 0) // { // foreach (ActionInstr ins in m.accesses) // { // ((CActBegin)cn).Addresses.Add(new MemAccess(ins.IsWrite, ins.Location, ins.ObjHandle, ins.Offset, ins.SrcLocation, mt.MachineId)); // } // } // } // } //} }
/// <summary> /// Updates the graph. /// </summary> /// <param name="machineTrace">MachineActionTrace</param> void UpdateGraph(MachineActionTrace machineTrace) { int currentMachineVC = 0; Node cLatestAction = null; foreach (MachineActionInfo info in machineTrace) { if (info.Type != MachineActionType.SendAction && (info.ActionId != 0)/* && !info.isTaskMachine*/) { ThreadTrace matching = null; try { matching = this.AllThreadTraces.Where(item => item.MachineId == info.MachineId && item.ActionId == info.ActionId).Single(); } catch (Exception) { //TODO: check correctness //In case entry and exit functions not defined. //IO.PrintLine("Skipping entry/exit actions: " + mt.MachineId + " " + mt.ActionId + " " + mt.ActionName); continue; } Node cn = new CActBegin(matching.MachineId, matching.ActionName, matching.ActionId, info.EventName, info.EventId); if(matching.ActionId == 1) { ((CActBegin)cn).IsStart = true; } cn.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn); if(cLatestAction != null) { this.CGraph.AddEdge(new Edge(cLatestAction, cn)); } Node cLatest = cn; cLatestAction = cn; bool createNew = false; foreach (ActionInstr ins in matching.Accesses) { // User trace send event. Node cn1; if (createNew) { Node cnn = new CActBegin(matching.MachineId, matching.ActionName, matching.ActionId, info.EventName, info.EventId); cnn.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cnn.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cnn); cn = cnn; this.CGraph.AddEdge(new Edge(cLatest, cn)); createNew = false; cLatest = cn; } if (ins.IsSend) { MachineActionInfo machineSend = machineTrace.Where( item => item.MachineId == matching.MachineId && item.SendId == ins.SendId).Single(); cn1 = new SendEvent(machineSend.MachineId, machineSend.SendId, machineSend.TargetMachineId, machineSend.EventName, machineSend.EventId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace create machine. else if (ins.IsCreate) { cn1 = new CreateMachine(ins.CreateMachineId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace task creation. else if (ins.IsTask) { cn1 = new CreateTask(ins.TaskId); cn1.VectorClock = new int[this.VcCount]; currentMachineVC++; try { cn1.VectorClock[info.MachineId] = currentMachineVC; } catch (Exception ex) { IO.PrintLine("failed: " + this.VcCount + " " + info.MachineId); IO.PrintLine(ex.ToString()); Environment.Exit(Environment.ExitCode); } this.CGraph.AddVertex(cn1); this.CGraph.AddEdge(new Edge(cLatest, cn1)); createNew = true; } // User trace reads/writes. else { ((CActBegin)cn).Addresses.Add(new MemAccess(ins.IsWrite, ins.Location, ins.ObjHandle, ins.Offset, ins.SrcLocation, info.MachineId)); cn1 = cn; } cLatest = cn1; cLatestAction = cn1; } } } }