diff --git a/Build.bat b/Build.bat index e1cf94e3b..22395e025 100644 --- a/Build.bat +++ b/Build.bat @@ -1,2 +1,6 @@ @echo off -build\nant-0.91-alpha2\bin\nant.exe -f:"%cd%"\default.build %1 \ No newline at end of file +build\nant-0.91-alpha2\bin\nant.exe -f:"%cd%"\default.build %1 +@echo. +@echo %date% +@echo %time% +@echo. \ No newline at end of file diff --git a/README.md b/README.md index 4d671b5d4..7d4fd890f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ You will need: 1. Visual Studio VS2013 (Community Edition) or later with C# and C++ 2. WiX 3.9 or later (http://wix.codeplex.com/releases/view/136891) 3. Specflow (http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee) +4. Windows SDK 8 and .NET Framework Tools (https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx) All other software should be included with this repository. @@ -84,10 +85,13 @@ No Git? Don't worry you can download the latest code as a [zip file](http://gith I would like to thank * JetBrains for my Open Source [ReSharper licence](http://www.jetbrains.com/resharper/), + + * [AppVeyor](https://ci.appveyor.com/project/sawilde/opencover) for allowing free build CI services for Open Source projects, * [Coveralls](https://coveralls.io/r/OpenCover/opencover) for allowing free services for Open Source projects, * NDepend for my [NDepend licence](http://www.ndepend.com/), * the guys at [CodeBetter](http://codebetter.com/), [Devlicious](http://devlicio.us/) and [Los Techies](http://lostechies.com/) who orignally arranged my MSDN licence all those years ago without which I doubt I'd have been able to start OpenCover (now no longer needed as we can build OpenCover using the VS2013 Community Edition), * the [NextGenUG](http://www.nxtgenug.net/) and their free swag from where I got lots of useful tools, + I'd also like to thank my family, employers, colleagues and friends for all their support. diff --git a/ReleaseNotes.tmp b/ReleaseNotes.tmp index b32197fc1..399c86ba9 100644 --- a/ReleaseNotes.tmp +++ b/ReleaseNotes.tmp @@ -1,4 +1,8 @@ Version [[version]] +#376 protect buffer allocation in multithreaded environment (fix) +#335 allow short wait timeout to be configured (feature) + +Version 4.6.210 (rc - remove) #282 exclude by process (feature) #246 auto crash reports (feature) #329 address ArgumentOutOfRangeException (potentially related to #274) (fix for VS2015) diff --git a/build/installer.build b/build/installer.build index b67a6a7f1..9ed75bcc2 100644 --- a/build/installer.build +++ b/build/installer.build @@ -21,6 +21,7 @@ + diff --git a/build/version.build b/build/version.build index 7a0a9a40e..3202eb215 100644 --- a/build/version.build +++ b/build/version.build @@ -2,7 +2,7 @@ - + @@ -10,8 +10,8 @@ - + @@ -37,4 +37,4 @@ - \ No newline at end of file + diff --git a/main/OpenCover.Console/Program.cs b/main/OpenCover.Console/Program.cs index e87483d16..328641ee3 100644 --- a/main/OpenCover.Console/Program.cs +++ b/main/OpenCover.Console/Program.cs @@ -74,7 +74,7 @@ static int Main(string[] args) { Logger.FatalFormat("An exception occured: {0}", ex.Message); Logger.FatalFormat("stack: {0}", ex.StackTrace); - Logger.FatalFormat("A report has been sent to the OenCover development team..."); + Logger.FatalFormat("A report has been sent to the OpenCover development team..."); } ReportCrash(ex); @@ -109,7 +109,7 @@ private static void ReportCrash(Exception exception) uploader.SendAnonymousReport(SendRequestState.GetClientLib(), state.GetApplication(), state.GetExceptionDescription(true)); } - catch (Exception ex) + catch (Exception) { System.Console.WriteLine("Failed to send crash report :("); } @@ -303,7 +303,7 @@ private static void RunService(CommandLineParser parser, Action + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + /// 2 public void Dispose() { if (_container == null) return; diff --git a/main/OpenCover.Framework/CommandLineParser.cs b/main/OpenCover.Framework/CommandLineParser.cs index a6d01570f..5fc4d91fb 100644 --- a/main/OpenCover.Framework/CommandLineParser.cs +++ b/main/OpenCover.Framework/CommandLineParser.cs @@ -113,7 +113,8 @@ public string Usage() builder.AppendLine(" [-hideskipped:File|Filter|Attribute|MissingPdb|All,[File|Filter|Attribute|MissingPdb|All]]"); builder.AppendLine(" [-log:[Off|Fatal|Error|Warn|Info|Debug|Verbose|All]]"); builder.AppendLine(" [-service[:byname]]"); - builder.AppendLine(" [-servicestarttimeout:1m23s"); + builder.AppendLine(" [-servicestarttimeout:"); + builder.AppendLine(" [-communicationtimeout:"); builder.AppendLine(" [-threshold:]"); builder.AppendLine(" [-enableperformancecounters]"); builder.AppendLine(" [-skipautoprops]"); @@ -190,6 +191,11 @@ public void ExtractAndValidateArguments() ReturnCodeOffset = ExtractValue("returntargetcode", () => { throw new InvalidOperationException("The return target code offset must be an integer"); }); break; + case "communicationtimeout": + CommunicationTimeout = ExtractValue("communicationtimeout", () => + { throw new InvalidOperationException(string.Format("The communication timeout must be an integer: {0}", GetArgumentValue("communicationtimeout"))); }); + CommunicationTimeout = Math.Max(Math.Min(CommunicationTimeout, 60000), 10000); + break; case "filter": Filters = ExtractFilters(GetArgumentValue("filter")); break; @@ -511,6 +517,11 @@ private void ValidateArguments() /// Instructs the console to print its version and exit /// public bool PrintVersion { get; private set; } + + /// + /// Sets the 'short' timeout between profiler and host (normally 10000ms) + /// + public int CommunicationTimeout { get; private set; } } } \ No newline at end of file diff --git a/main/OpenCover.Framework/Communication/CommunicationManager.cs b/main/OpenCover.Framework/Communication/CommunicationManager.cs index c737ae9e7..b2b1dce5b 100644 --- a/main/OpenCover.Framework/Communication/CommunicationManager.cs +++ b/main/OpenCover.Framework/Communication/CommunicationManager.cs @@ -1,10 +1,7 @@ using System; -using System.Diagnostics; using System.IO; using System.Threading; -using log4net.Repository.Hierarchy; using OpenCover.Framework.Manager; -using OpenCover.Framework.Service; namespace OpenCover.Framework.Communication { @@ -48,6 +45,11 @@ public CommunicationManager(IMessageHandler messageHandler) _messageHandler = messageHandler; } + /// + /// Process a communication related message from a profiler + /// + /// + /// public void HandleCommunicationBlock(IManagedCommunicationBlock mcb, Action offloadHandling) { mcb.ProfilerRequestsInformation.Reset(); @@ -71,6 +73,10 @@ private static void SendChunkAndWaitForConfirmation(int writeSize, IManagedCommu mcb.InformationReadByProfiler.Reset(); } + /// + /// process a results block from the profiler + /// + /// public byte[] HandleMemoryBlock(IManagedMemoryBlock mmb) { mmb.ProfilerHasResults.Reset(); @@ -88,6 +94,9 @@ public byte[] HandleMemoryBlock(IManagedMemoryBlock mmb) return newData; } + /// + /// Communication is over + /// public void Complete() { _messageHandler.Complete(); diff --git a/main/OpenCover.Framework/Communication/MarshalWapper.cs b/main/OpenCover.Framework/Communication/MarshalWapper.cs index 1f4f71d33..1531b7000 100644 --- a/main/OpenCover.Framework/Communication/MarshalWapper.cs +++ b/main/OpenCover.Framework/Communication/MarshalWapper.cs @@ -39,11 +39,24 @@ public interface IMarshalWrapper /// public class MarshalWrapper : IMarshalWrapper { + /// + /// Map pinned memory to a structure + /// + /// The type of the structure + /// + /// public T PtrToStructure(IntPtr pinnedMemory) { return (T)Marshal.PtrToStructure(pinnedMemory, typeof(T)); } + /// + /// Map a structure to pinned memory + /// + /// + /// + /// + /// public void StructureToPtr(T structure, IntPtr pinnedMemory, bool fDeleteOld) { Marshal.StructureToPtr(structure, pinnedMemory, fDeleteOld); diff --git a/main/OpenCover.Framework/Communication/MessageHandler.cs b/main/OpenCover.Framework/Communication/MessageHandler.cs index 99f246257..d49a1152b 100644 --- a/main/OpenCover.Framework/Communication/MessageHandler.cs +++ b/main/OpenCover.Framework/Communication/MessageHandler.cs @@ -67,6 +67,14 @@ public MessageHandler(IProfilerCommunication profilerCommunication, IMarshalWrap _memoryManager = memoryManager; } + /// + /// Process a Standard Message + /// + /// + /// + /// + /// + /// public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action chunkReady, Action offloadHandling) { IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject(); @@ -319,6 +327,9 @@ private int HandleTrackProcessMessage(IntPtr pinnedMemory) private int _readSize; + /// + /// Maximum size of a base message + /// public int ReadSize { get @@ -344,6 +355,9 @@ public int ReadSize } } + /// + /// Finished + /// public void Complete() { _profilerCommunication.Stopping(); diff --git a/main/OpenCover.Framework/Communication/Messages.cs b/main/OpenCover.Framework/Communication/Messages.cs index ba1e40846..49c423669 100644 --- a/main/OpenCover.Framework/Communication/Messages.cs +++ b/main/OpenCover.Framework/Communication/Messages.cs @@ -10,7 +10,8 @@ namespace OpenCover.Framework.Communication /// /// The command supportd by the host /// -// ReSharper disable InconsistentNaming + // ReSharper disable InconsistentNaming + // ReSharper disable once EnumUnderlyingTypeIsInt public enum MSG_Type : int { /// @@ -338,8 +339,15 @@ public struct MSG_AllocateBuffer_Request [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct MSG_AllocateBuffer_Response { + /// + /// is the buffer allocated + /// [MarshalAs(UnmanagedType.Bool)] public bool allocated; + + /// + /// The id assigned to the buffer + /// public uint bufferId; } diff --git a/main/OpenCover.Framework/Filter.cs b/main/OpenCover.Framework/Filter.cs index 1501cb276..5211ddd69 100644 --- a/main/OpenCover.Framework/Filter.cs +++ b/main/OpenCover.Framework/Filter.cs @@ -5,7 +5,6 @@ // using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.CompilerServices; @@ -25,6 +24,10 @@ public class Filter : IFilter internal IList ExcludedAttributes { get; private set; } internal IList ExcludedFiles { get; private set; } internal IList TestFiles { get; private set; } + + /// + /// Are the filters supplied as reguar expressions + /// public bool RegExFilters { get; private set; } @@ -42,6 +45,13 @@ public Filter(bool useRegexFilters = false) RegExFilters = useRegexFilters; } + /// + /// Decides whether an assembly should be included in the instrumentation + /// + /// The name of the process being profiled + /// the name of the assembly under profile + /// All assemblies matching either the inclusion or exclusion filter should be included + /// as it is the class that is being filtered within these unless the class filter is * public bool UseAssembly(string processName, string assemblyName) { processName = Path.GetFileNameWithoutExtension(processName); @@ -65,6 +75,13 @@ public bool UseAssembly(string processName, string assemblyName) return false; } + /// + /// Determine if an [assemblyname]classname pair matches the current Exclusion or Inclusion filters + /// + /// The name of the process + /// the name of the assembly under profile + /// the name of the class under profile + /// false - if pair matches the exclusion filter or matches no filters, true - if pair matches in the inclusion filter public bool InstrumentClass(string processName, string assemblyName, string className) { if (string.IsNullOrEmpty(processName) || string.IsNullOrEmpty(assemblyName) || string.IsNullOrEmpty(className)) @@ -96,11 +113,23 @@ public bool InstrumentClass(string processName, string assemblyName, string clas } + /// + /// Determine if an [assemblyname]classname pair matches the current Exclusion or Inclusion filters + /// + /// the name of the assembly under profile + /// the name of the class under profile + /// false - if pair matches the exclusion filter or matches no filters, true - if pair matches in the inclusion filter public bool InstrumentClass(string assemblyName, string className) { return InstrumentClass(Guid.NewGuid().ToString(), assemblyName, className); } + /// + /// Add a filter + /// + /// A filter is of the format (+ or -)[assemblyName]className, wildcards are allowed.
+ /// i.e. -[mscorlib], -[System.*]*, +[App.*]*, +[*]* + /// public void AddFilter(string assemblyClassName) { string assemblyName; @@ -154,11 +183,20 @@ private static InvalidOperationException InvalidFilterFormatException(string ass return new InvalidOperationException(string.Format("The supplied filter '{0}' does not meet the required format for a filter +-[assemblyname]classname", assemblyClassName)); } + /// + /// Add attribute exclusion filters + /// + /// An array of filters that are used to wildcard match an attribute public void AddAttributeExclusionFilters(string[] exclusionFilters) { ExcludedAttributes.AddFilters(exclusionFilters, RegExFilters); } + /// + /// Is this entity (method/type) excluded due to an attributeFilter + /// + /// The entity to test + /// public bool ExcludeByAttribute(IMemberDefinition entity) { if (ExcludedAttributes.Count == 0) @@ -207,6 +245,11 @@ where excludeAttribute.IsMatchingExpression(customAttribute.AttributeType.FullNa select excludeAttribute).Any(); } + /// + /// Is this entity excluded due to an attributeFilter + /// + /// The entity to test + /// public bool ExcludeByAttribute(AssemblyDefinition entity) { if (ExcludedAttributes.Count == 0) @@ -215,6 +258,11 @@ public bool ExcludeByAttribute(AssemblyDefinition entity) return ExcludeByAttribute((ICustomAttributeProvider)entity); } + /// + /// Is this file excluded + /// + /// The name of the file to test + /// public bool ExcludeByFile(string fileName) { if (ExcludedFiles.Count == 0 || string.IsNullOrWhiteSpace(fileName)) @@ -223,11 +271,20 @@ public bool ExcludeByFile(string fileName) return ExcludedFiles.Any(excludeFile => excludeFile.IsMatchingExpression(fileName)); } + /// + /// Add file exclusion filters + /// + /// public void AddFileExclusionFilters(string[] exclusionFilters) { ExcludedFiles.AddFilters(exclusionFilters, RegExFilters); } + /// + /// Decides whether an assembly should be analysed for test methods + /// + /// the name of the assembly under profile + /// true - if the assembly matches the test assembly filter public bool UseTestAssembly(string assemblyName) { if (TestFiles.Count == 0 || string.IsNullOrWhiteSpace(assemblyName)) @@ -236,11 +293,20 @@ public bool UseTestAssembly(string assemblyName) return TestFiles.Any(file => file.IsMatchingExpression(assemblyName)); } + /// + /// Add test file filters + /// + /// public void AddTestFileFilters(string[] testFilters) { TestFiles.AddFilters(testFilters, RegExFilters); } + /// + /// Is the method an auto-implemented property get/set + /// + /// + /// public bool IsAutoImplementedProperty(MethodDefinition method) { if ((method.IsSetter || method.IsGetter) && method.HasCustomAttributes) @@ -250,6 +316,11 @@ public bool IsAutoImplementedProperty(MethodDefinition method) return false; } + /// + /// Should we instrument this asssembly + /// + /// + /// public bool InstrumentProcess(string processName) { if (string.IsNullOrEmpty(processName)) diff --git a/main/OpenCover.Framework/ICommandLine.cs b/main/OpenCover.Framework/ICommandLine.cs index 93a295475..eb697c417 100644 --- a/main/OpenCover.Framework/ICommandLine.cs +++ b/main/OpenCover.Framework/ICommandLine.cs @@ -53,5 +53,10 @@ public interface ICommandLine /// Should auto implemented properties be skipped ///
bool SkipAutoImplementedProperties { get; } + + /// + /// Sets the 'short' timeout between profiler and host + /// + int CommunicationTimeout { get; } } } \ No newline at end of file diff --git a/main/OpenCover.Framework/Manager/MemoryManager.cs b/main/OpenCover.Framework/Manager/MemoryManager.cs index c97604ef1..b034b849c 100644 --- a/main/OpenCover.Framework/Manager/MemoryManager.cs +++ b/main/OpenCover.Framework/Manager/MemoryManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.IO.MemoryMappedFiles; using System.Linq; @@ -28,7 +27,12 @@ public class MemoryManager : IMemoryManager /// public class ManagedBlock { + /// + /// protected string Namespace; + + /// + /// protected string Key; /// @@ -343,6 +347,10 @@ public void RemoveDeactivatedBlocks() } } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + /// 2 public void Dispose() { lock (_lockObject) diff --git a/main/OpenCover.Framework/Manager/ProfilerManager.cs b/main/OpenCover.Framework/Manager/ProfilerManager.cs index 545776677..054465aa8 100644 --- a/main/OpenCover.Framework/Manager/ProfilerManager.cs +++ b/main/OpenCover.Framework/Manager/ProfilerManager.cs @@ -127,7 +127,12 @@ private void SetProfilerAttributesOnDictionary(string profilerKey, string profil dictionary["Cor_Enable_Profiling"] = "1"; dictionary["CoreClr_Profiler"] = ProfilerGuid; dictionary["CoreClr_Enable_Profiling"] = "1"; - + dictionary["Cor_Profiler_Path"] = string.Empty; + dictionary["CorClr_Profiler_Path"] = string.Empty; + + if (_commandLine.CommunicationTimeout > 0) + dictionary["OpenCover_Profiler_ShortWait"] = _commandLine.CommunicationTimeout.ToString(); + switch (_commandLine.Registration) { case Registration.Path32: @@ -151,7 +156,7 @@ private WaitCallback SaveVisitData(EventWaitHandle queueMgmt) { byte[] data; while (!_messageQueue.TryDequeue(out data)) - Thread.Yield(); + ThreadHelper.YieldOrSleep(100); _perfCounters.CurrentMemoryQueueSize = _messageQueue.Count; _perfCounters.IncrementBlocksReceived(); @@ -226,15 +231,22 @@ private void ProcessMessages(WaitHandle[] handles) .Select(g => g.Select(a => a.Pair).ToList()) .Select(g => Task.Factory.StartNew(() => { - g.Select(h => h.Item1).ToList().ForEach(h => h.Set()); - WaitHandle.WaitAll(g.Select(h => h.Item2).ToArray(), new TimeSpan(0, 0, 20)); + ConsumeException(() => + { + g.Select(h => h.Item1).ToList().ForEach(h => h.Set()); + WaitHandle.WaitAll(g.Select(h => h.Item2).ToArray(), new TimeSpan(0, 0, 20)); + }); })).ToArray(); Task.WaitAll(tasks); foreach (var threadHandle in threadHandles) { - threadHandle.Item1.Dispose(); - threadHandle.Item2.Dispose(); + var handle = threadHandle; + ConsumeException(() => + { + handle.Item1.Dispose(); + handle.Item2.Dispose(); + }); } threadHandles.Clear(); } @@ -243,6 +255,18 @@ private void ProcessMessages(WaitHandle[] handles) _messageQueue.Enqueue(new byte[0]); } + // wrap exceptions when closing down + private static void ConsumeException(Action doSomething) + { + try + { + doSomething(); + } + catch (Exception ex) + { + DebugLogger.Error("An unexpected exception was encountered but consumed.", ex); + } + } private Tuple StartProcessingThread(ManagedBufferBlock block) { DebugLogger.InfoFormat("Starting Process Block => {0}", block.BufferId); @@ -289,7 +313,7 @@ private WaitCallback ProcessBlock(ManagedBufferBlock block, { do { - Thread.Yield(); + ThreadHelper.YieldOrSleep(100); } while (_messageQueue.Count > 200); } break; diff --git a/main/OpenCover.Framework/Model/Class.cs b/main/OpenCover.Framework/Model/Class.cs index c7df3e252..9e4167973 100644 --- a/main/OpenCover.Framework/Model/Class.cs +++ b/main/OpenCover.Framework/Model/Class.cs @@ -37,6 +37,10 @@ public Class() /// public Method[] Methods { get; set; } + /// + /// If a class was skipped by instrumentation, supply the reason why + /// + /// public override void MarkAsSkipped(SkippedMethod reason) { SkippedDueTo = reason; diff --git a/main/OpenCover.Framework/Model/File.cs b/main/OpenCover.Framework/Model/File.cs index b21492d84..002d94377 100644 --- a/main/OpenCover.Framework/Model/File.cs +++ b/main/OpenCover.Framework/Model/File.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Xml.Serialization; @@ -17,6 +16,9 @@ namespace OpenCover.Framework.Model /// public class FileRef { + /// + /// The uniqueid of a file in a coverage session + /// [XmlAttribute("uid")] public UInt32 UniqueId { get; set; } } diff --git a/main/OpenCover.Framework/Model/InstrumentationModelBuilderFactory.cs b/main/OpenCover.Framework/Model/InstrumentationModelBuilderFactory.cs index 160356ea9..470ab72e4 100644 --- a/main/OpenCover.Framework/Model/InstrumentationModelBuilderFactory.cs +++ b/main/OpenCover.Framework/Model/InstrumentationModelBuilderFactory.cs @@ -35,6 +35,12 @@ public InstrumentationModelBuilderFactory(ICommandLine commandLine, IFilter filt _trackedMethodStrategyManager = trackedMethodStrategyManager; } + /// + /// Create a Model Builder for a module + /// + /// + /// + /// public IInstrumentationModelBuilder CreateModelBuilder(string modulePath, string moduleName) { var manager = new CecilSymbolManager(_commandLine, _filter, _logger, _trackedMethodStrategyManager); diff --git a/main/OpenCover.Framework/Model/InstrumentationPoint.cs b/main/OpenCover.Framework/Model/InstrumentationPoint.cs index fbfe6a742..68266f38f 100644 --- a/main/OpenCover.Framework/Model/InstrumentationPoint.cs +++ b/main/OpenCover.Framework/Model/InstrumentationPoint.cs @@ -13,6 +13,7 @@ namespace OpenCover.Framework.Model public class InstrumentationPoint { private static int _instrumentPoint; + private static object _addInstrumentPointSync = new object(); private static readonly List InstrumentPoints; static InstrumentationPoint() @@ -114,10 +115,13 @@ public static bool AddVisitCount(uint spid, uint trackedMethodId, int sum = 1) /// public InstrumentationPoint() { - UniqueSequencePoint = (uint)Interlocked.Increment(ref _instrumentPoint); - InstrumentPoints.Add(this); - OrigSequencePoint = UniqueSequencePoint; - } + lock (_addInstrumentPointSync) + { + UniqueSequencePoint = (uint)++_instrumentPoint; + InstrumentPoints.Add(this); + OrigSequencePoint = UniqueSequencePoint; + } + } /// /// Store the number of visits diff --git a/main/OpenCover.Framework/Model/Method.cs b/main/OpenCover.Framework/Model/Method.cs index afb790437..4279d3f64 100644 --- a/main/OpenCover.Framework/Model/Method.cs +++ b/main/OpenCover.Framework/Model/Method.cs @@ -3,7 +3,8 @@ // // This source code is released under the MIT License; see the accompanying license file. // -using System.Collections.Generic; +using System; +using System.Text.RegularExpressions; using System.Xml.Serialization; namespace OpenCover.Framework.Model @@ -95,6 +96,10 @@ public class Method : SummarySkippedEntity [XmlAttribute("isSetter")] public bool IsSetter { get; set; } + /// + /// Mark an entity as skipped + /// + /// Provide a reason public override void MarkAsSkipped(SkippedMethod reason) { SkippedDueTo = reason; @@ -103,5 +108,46 @@ public override void MarkAsSkipped(SkippedMethod reason) SequencePoints = null; BranchPoints = null; } + /// + /// method name excluding return type, namespace and arguments + /// + public string shortName { + get { + if (String.IsNullOrWhiteSpace(this.Name)) return ""; + int startIndex = this.Name.IndexOf("::", StringComparison.Ordinal); + int finalIndex = this.Name.IndexOf('(', startIndex); + return this.Name + .Substring(startIndex, finalIndex - startIndex) + .Substring(2); + } + } + + /* Compiler Generated Name Examples + System.Boolean DD.Collections.BitSetArray/<Complement>d__e::MoveNext() + System.Boolean DD.Collections.BitSetArray::<_SetItems>b__b(System.Int32) + System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32) + + [^\s]+\s[^\s|/|:]+(/\w*)?(::(.+_)?)?(<\w+>[a-z]__\w(\w|_\w)?)(::.+)?(\(.*\))$ + */ + /// + /// True if method name matches isGeneratedMethodRegex pattern + /// + public bool isGenerated { + get { + return (!String.IsNullOrWhiteSpace(this.Name) + && this.Name.Contains("__") + && isGeneratedMethodRegex.IsMatch(this.Name) + ); + } + } + private const RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture; + private readonly Regex isGeneratedMethodRegex = new Regex(@"(<[^\s|>]+>[a-z]__\w(\w|_\w)?)(::([^\s|\(]+))?(\([^\s|\)]*\))$", regexOptions); + + /* + code sample + Match match = generatedMethodItems.Match(sample); + if (match.Success) Console.WriteLine(match.Groups["returnType"].Value); + */ + private readonly Regex generatedMethodItems = new Regex(@"(?[^\s]+)\s(?[^\s|/]+/)?(?[^\s|:]+::)?(<(?[^\s|>]+)>[a-z]__\w(\w|_\w)?)(::(?[^\s|\(]+))?(\([^\s|\)]*\))$", regexOptions); } } diff --git a/main/OpenCover.Framework/Model/Module.cs b/main/OpenCover.Framework/Model/Module.cs index c6817e602..0a3b2bd6e 100644 --- a/main/OpenCover.Framework/Model/Module.cs +++ b/main/OpenCover.Framework/Model/Module.cs @@ -3,10 +3,8 @@ // // This source code is released under the MIT License; see the accompanying license file. // -using System; + using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Xml.Serialization; namespace OpenCover.Framework.Model @@ -61,6 +59,10 @@ public Module() [XmlAttribute("hash")] public string ModuleHash { get; set; } + /// + /// Mark an entity as skipped + /// + /// Provide a reason public override void MarkAsSkipped(SkippedMethod reason) { SkippedDueTo = reason; diff --git a/main/OpenCover.Framework/Model/SequencePoint.cs b/main/OpenCover.Framework/Model/SequencePoint.cs index db19eb4a0..d39a48f5a 100644 --- a/main/OpenCover.Framework/Model/SequencePoint.cs +++ b/main/OpenCover.Framework/Model/SequencePoint.cs @@ -4,6 +4,7 @@ // This source code is released under the MIT License; see the accompanying license file. // +using System; using System.Collections.Generic; using System.Xml.Serialization; @@ -12,7 +13,7 @@ namespace OpenCover.Framework.Model /// /// a sequence point /// - public class SequencePoint : InstrumentationPoint, IDocumentReference + public class SequencePoint : InstrumentationPoint, IDocumentReference, IEquatable { /// /// The start line of the sequence point @@ -37,10 +38,19 @@ public class SequencePoint : InstrumentationPoint, IDocumentReference /// [XmlAttribute("ec")] public int EndColumn { get; set; } - + + /// + /// Count of merged branches + /// + /// + /// The number of branch exits + /// [XmlAttribute("bec")] public int BranchExitsCount { get; set; } + /// + /// Visit count of merged branches + /// [XmlAttribute("bev")] public int BranchExitsVisit { get; set; } @@ -57,5 +67,54 @@ public class SequencePoint : InstrumentationPoint, IDocumentReference public string Document { get; set; } internal List BranchPoints { get; set; } + + /// + /// Property + /// + public bool isSingleCharSequencePoint { + get { + return (this.StartLine == this.EndLine) && (this.EndColumn - this.StartColumn) == 1; + } + } + + #region IEquatable implementation + + /// + /// Override GetHashCode + /// + /// int + public override int GetHashCode () { + return unchecked (this.StartLine << 3) ^ unchecked (this.EndLine << 2) ^ unchecked (this.StartColumn << 1) ^ (this.EndColumn); + } + + /// + /// Override Equals + /// + /// Object + /// bool + public override bool Equals (Object obj) { + if (ReferenceEquals(this, obj)) { + return true; + } + var that = obj as SequencePoint; + return !ReferenceEquals(that, null) && this.Equals(that); + } + + /// + /// IEquatable<SequencePoint>.Equals implementation + /// + /// SequencePoint + /// bool + bool IEquatable.Equals(SequencePoint other) + { + return !ReferenceEquals(other, null) + && this.Document == other.Document + && this.StartLine == other.StartLine + && this.StartColumn == other.StartColumn + && this.EndLine == other.EndLine + && this.EndColumn == other.EndColumn; + } + + #endregion } } diff --git a/main/OpenCover.Framework/Model/SkippedEntity.cs b/main/OpenCover.Framework/Model/SkippedEntity.cs index ed771710c..c447ea754 100644 --- a/main/OpenCover.Framework/Model/SkippedEntity.cs +++ b/main/OpenCover.Framework/Model/SkippedEntity.cs @@ -7,7 +7,7 @@ namespace OpenCover.Framework.Model /// public abstract class SkippedEntity { - private SkippedMethod? skippedDueTo; + private SkippedMethod? _skippedDueTo; /// /// If this class has been skipped then this value will describe why @@ -15,14 +15,14 @@ public abstract class SkippedEntity [XmlAttribute("skippedDueTo")] public SkippedMethod SkippedDueTo { - get { return skippedDueTo.GetValueOrDefault(); } - set { skippedDueTo = value; } + get { return _skippedDueTo.GetValueOrDefault(); } + set { _skippedDueTo = value; } } /// /// If this class has been skipped then this value will allow the data to be serialized /// - public bool ShouldSerializeSkippedDueTo() { return skippedDueTo.HasValue; } + public bool ShouldSerializeSkippedDueTo() { return _skippedDueTo.HasValue; } /// /// Mark an entity as skipped diff --git a/main/OpenCover.Framework/Model/SummarySkippedEntity.cs b/main/OpenCover.Framework/Model/SummarySkippedEntity.cs index 1c305c7f7..42f2bbccd 100644 --- a/main/OpenCover.Framework/Model/SummarySkippedEntity.cs +++ b/main/OpenCover.Framework/Model/SummarySkippedEntity.cs @@ -6,6 +6,9 @@ namespace OpenCover.Framework.Model /// public abstract class SummarySkippedEntity : SkippedEntity { + /// + /// Initialise + /// protected SummarySkippedEntity() { Summary = new Summary(); diff --git a/main/OpenCover.Framework/Model/TrackedMethod.cs b/main/OpenCover.Framework/Model/TrackedMethod.cs index f73b3f99c..3a742b84f 100644 --- a/main/OpenCover.Framework/Model/TrackedMethod.cs +++ b/main/OpenCover.Framework/Model/TrackedMethod.cs @@ -18,7 +18,9 @@ public class TrackedMethodRef [XmlAttribute("uid")] public UInt32 UniqueId { get; set; } - // visit count + /// + /// The visit count + /// [XmlAttribute("vc")] public int VisitCount { get; set; } diff --git a/main/OpenCover.Framework/OpenCover.Framework.csproj b/main/OpenCover.Framework/OpenCover.Framework.csproj index cec4d7b0a..6f316da8d 100644 --- a/main/OpenCover.Framework/OpenCover.Framework.csproj +++ b/main/OpenCover.Framework/OpenCover.Framework.csproj @@ -145,8 +145,11 @@ + + + diff --git a/main/OpenCover.Framework/Persistance/BasePersistance.cs b/main/OpenCover.Framework/Persistance/BasePersistance.cs index d09e25b1b..17be3a104 100644 --- a/main/OpenCover.Framework/Persistance/BasePersistance.cs +++ b/main/OpenCover.Framework/Persistance/BasePersistance.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using OpenCover.Framework.Communication; using OpenCover.Framework.Model; +using OpenCover.Framework.Utility; using log4net; namespace OpenCover.Framework.Persistance @@ -12,6 +14,11 @@ namespace OpenCover.Framework.Persistance /// public abstract class BasePersistance : IPersistance { + private static readonly object Protection = new object(); + + /// + /// Provides subclasses access to the command line object + /// protected readonly ICommandLine CommandLine; private readonly ILog _logger; private uint _trackedMethodId; @@ -47,15 +54,23 @@ public void PersistModule(Module module) module.Classes = module.Classes ?? new Class[0]; if (CommandLine.MergeByHash) { - var modules = CoverageSession.Modules ?? new Module[0]; - var existingModule = modules.FirstOrDefault(x => x.ModuleHash == module.ModuleHash); - if (existingModule!=null) + lock (Protection) { - if (!existingModule.Aliases.Any(x=>x.Equals(module.FullName, StringComparison.InvariantCultureIgnoreCase))) + var modules = CoverageSession.Modules ?? new Module[0]; + lock (Protection) { - existingModule.Aliases.Add(module.FullName); + var existingModule = modules.FirstOrDefault(x => x.ModuleHash == module.ModuleHash); + if (existingModule != null) + { + if ( + !existingModule.Aliases.Any( + x => x.Equals(module.FullName, StringComparison.InvariantCultureIgnoreCase))) + { + existingModule.Aliases.Add(module.FullName); + } + return; + } } - return; } } @@ -76,12 +91,12 @@ protected void ClearCoverageSession() } /// - /// + /// /// /// protected void ReassignCoverageSession(CoverageSession session) { - _moduleMethodMap.Clear(); + _moduleMethodMap.Clear(); CoverageSession = session; CoverageSession.Summary = new Summary(); foreach (var module in CoverageSession.Modules) @@ -130,8 +145,10 @@ private void BuildMethodMapForModule(Module module) /// public bool IsTracking(string modulePath) { - return CoverageSession.Modules.Any(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase)) && - !x.ShouldSerializeSkippedDueTo()); + lock (Protection) { + return CoverageSession.Modules.Any(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase)) && + !x.ShouldSerializeSkippedDueTo()); + } } /// @@ -139,39 +156,41 @@ public bool IsTracking(string modulePath) /// public virtual void Commit() { - PopulateInstrumentedPoints(); + if (CoverageSession.Modules != null) { + MarkSkippedMethods(); + if (CommandLine.HideSkipped != null && CommandLine.HideSkipped.Any()) { + foreach (var skippedMethod in CommandLine.HideSkipped.OrderBy(x => x)) + { + switch (skippedMethod) + { + case SkippedMethod.File: + RemoveSkippedMethods(SkippedMethod.File); + RemoveEmptyClasses(); + RemoveUnreferencedFiles(); + break; + case SkippedMethod.Filter: + RemoveSkippedModules(SkippedMethod.Filter); + RemoveSkippedClasses(SkippedMethod.Filter); + break; + case SkippedMethod.MissingPdb: + RemoveSkippedModules(SkippedMethod.MissingPdb); + break; + case SkippedMethod.Attribute: + RemoveSkippedClasses(SkippedMethod.Attribute); + RemoveSkippedMethods(SkippedMethod.Attribute); + RemoveEmptyClasses(); + break; + case SkippedMethod.AutoImplementedProperty: + RemoveSkippedMethods(SkippedMethod.Attribute); + RemoveEmptyClasses(); + break; + } + } + } + TransformSequences(); + CalculateCoverage(); + } - if (CommandLine.HideSkipped == null) return; - - if (!CommandLine.HideSkipped.Any()) return; - - foreach (var skippedMethod in CommandLine.HideSkipped.OrderBy(x => x)) - { - switch (skippedMethod) - { - case SkippedMethod.File: - RemoveSkippedMethods(SkippedMethod.File); - RemoveEmptyClasses(); - RemoveUnreferencedFiles(); - break; - case SkippedMethod.Filter: - RemoveSkippedModules(SkippedMethod.Filter); - RemoveSkippedClasses(SkippedMethod.Filter); - break; - case SkippedMethod.MissingPdb: - RemoveSkippedModules(SkippedMethod.MissingPdb); - break; - case SkippedMethod.Attribute: - RemoveSkippedClasses(SkippedMethod.Attribute); - RemoveSkippedMethods(SkippedMethod.Attribute); - RemoveEmptyClasses(); - break; - case SkippedMethod.AutoImplementedProperty: - RemoveSkippedMethods(SkippedMethod.Attribute); - RemoveEmptyClasses(); - break; - } - } } private void RemoveSkippedModules(SkippedMethod skipped) @@ -223,17 +242,15 @@ private void RemoveUnreferencedFiles() if (CoverageSession.Modules == null) return; foreach (var module in CoverageSession.Modules) { - module.Files = (from file in module.Files ?? new File[0] + module.Files = (from file in module.Files ?? new File[0] from @class in module.Classes ?? new Class[0] where (@class.Methods ?? new Method[0]).Where(x=>x.FileRef != null).Any(x => x.FileRef.UniqueId == file.UniqueId) select file).Distinct().ToArray(); } } - private void PopulateInstrumentedPoints() - { - if (CoverageSession.Modules == null) return; - + private void MarkSkippedMethods() + { foreach (var method in from @class in (from module in CoverageSession.Modules from @class in module.Classes ?? new Class[0] @@ -245,119 +262,25 @@ from method in @class.Methods.Where(x => !x.ShouldSerializeSkippedDueTo()) { method.MarkAsSkipped(SkippedMethod.Inferred); } - + } + + private void CalculateCoverage() + { foreach (var module in CoverageSession.Modules.Where(x => !x.ShouldSerializeSkippedDueTo())) { - - #region Module File/FileID Dictionary - - var filesDictionary = new Dictionary(); - foreach (var file in (module.Files ?? new File[0]).Where(file => !filesDictionary.ContainsKey(file.FullPath ?? ""))) - { - filesDictionary.Add(file.FullPath ?? "", file.UniqueId); - } - - #endregion - foreach (var @class in (module.Classes ?? new Class[0]).Where(x => !x.ShouldSerializeSkippedDueTo())) { - foreach (var method in (@class.Methods ?? new Method[0]).Where(x => !x.ShouldSerializeSkippedDueTo())) { - var sequencePoints = method.SequencePoints ?? new SequencePoint[0]; - var branchPoints = method.BranchPoints ?? new BranchPoint[0]; - - MapFileReferences(sequencePoints, filesDictionary); - MapFileReferences(branchPoints, filesDictionary); - - #region Merge branch-exits - - // anything to merge? - if (sequencePoints.Length != 0 && branchPoints.Length != 0) { - - #region Join Sequences and Branches - - var index = 0; - - // get first sequencePoint and prepare list for Add(branchPoint) - var parent = sequencePoints[index]; - parent.BranchPoints = new List(); - - // get nextOffset - int nextOffset = index + 1 < sequencePoints.Length ? sequencePoints[index + 1].Offset : int.MaxValue; - - foreach (var branchPoint in branchPoints) { - - // while branchPoint belongs to next sequencePoint - // nextOffset is offset of next sequencePoint - // or unreachable int.MinValue - while (branchPoint.Offset > nextOffset) { - - // increment index to next sequencePoint - ++index; - - // get next sequencePoint and prepare list for Add(branchPoint) - parent = sequencePoints[index]; - parent.BranchPoints = new List(); - - // get nextOffset - if (index + 1 < sequencePoints.Length) { - nextOffset = sequencePoints[index + 1].Offset; - } - else { - nextOffset = int.MaxValue; - } - } - // join BranchPoint to SequencePoint - parent.BranchPoints.Add(branchPoint); - } - - #endregion - - #region Merge each Sequence Branch-Exits - - var branchExits = new Dictionary(); - foreach (var sequencePoint in sequencePoints) { - - // SequencePoint has branches attached? - if (sequencePoint.BranchPoints != null && sequencePoint.BranchPoints.Count != 0) { - - // Merge SP.BranchPoints using EndOffset as branchExits key - branchExits.Clear(); - foreach (var branchPoint in sequencePoint.BranchPoints) { - if (!branchExits.ContainsKey(branchPoint.EndOffset)) { - branchExits[branchPoint.EndOffset] = branchPoint; // insert branch - } else { - branchExits[branchPoint.EndOffset].VisitCount += branchPoint.VisitCount; // update branch - } - } - - // Update SequencePoint properties/attributes - sequencePoint.BranchExitsCount = 0; - sequencePoint.BranchExitsVisit = 0; - foreach (var branchPoint in branchExits.Values) { - sequencePoint.BranchExitsCount += 1; - sequencePoint.BranchExitsVisit += branchPoint.VisitCount == 0 ? 0 : 1; - } - } - sequencePoint.BranchPoints = null; // release memory - } - - #endregion - - } - - #endregion - if (method.MethodPoint != null) { method.Visited = (method.MethodPoint.VisitCount > 0); } - method.Summary.NumBranchPoints = branchPoints.Count(); - method.Summary.VisitedBranchPoints = branchPoints.Count(pt => pt.VisitCount != 0); - method.Summary.NumSequencePoints = sequencePoints.Count(); - method.Summary.VisitedSequencePoints = sequencePoints.Count(pt => pt.VisitCount != 0); + method.Summary.NumBranchPoints = method.BranchPoints.Count(); + method.Summary.VisitedBranchPoints = method.BranchPoints.Count(pt => pt.VisitCount != 0); + method.Summary.NumSequencePoints = method.SequencePoints.Count(); + method.Summary.VisitedSequencePoints = method.SequencePoints.Count(pt => pt.VisitCount != 0); if (method.Summary.NumSequencePoints > 0) method.Summary.NumBranchPoints += 1; @@ -386,7 +309,7 @@ from method in @class.Methods.Where(x => !x.ShouldSerializeSkippedDueTo()) @class.Summary.MaxCyclomaticComplexity = Math.Max(@class.Summary.MaxCyclomaticComplexity, method.CyclomaticComplexity); } - @class.Summary.NumClasses = (@class.Summary.NumMethods > 0) ? 1 : 0; + @class.Summary.NumClasses = (@class.Summary.NumMethods > 0) ? 1 : 0; @class.Summary.VisitedClasses = (@class.Summary.VisitedMethods > 0) ? 1 : 0; AddPoints(module.Summary, @class.Summary); @@ -408,11 +331,10 @@ from method in @class.Methods.Where(x => !x.ShouldSerializeSkippedDueTo()) CoverageSession.Summary.MinCyclomaticComplexity = Math.Min(CoverageSession.Summary.MinCyclomaticComplexity, module.Summary.MinCyclomaticComplexity); CoverageSession.Summary.MaxCyclomaticComplexity = Math.Max(CoverageSession.Summary.MaxCyclomaticComplexity, module.Summary.MaxCyclomaticComplexity); } - CalculateCoverage(CoverageSession.Summary); } - private static void MapFileReferences(IEnumerable points, IDictionary filesDictionary) + private static void MapFileReferences(IEnumerable points, IDictionary filesDictionary) { foreach (var pt in points.Where(p => p.FileId == 0)) { @@ -468,7 +390,7 @@ public bool GetSequencePointsForFunction(string modulePath, int functionToken, o sequencePoints = points.ToArray(); return true; } - return false; + return false; } /// @@ -503,13 +425,17 @@ private Method GetMethod(string modulePath, int functionToken, out Class @class) { @class = null; //c = null; - var module = CoverageSession.Modules.FirstOrDefault(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase))); - if (module == null) - return null; - if (!_moduleMethodMap[module].ContainsKey(functionToken)) return null; - var pair = _moduleMethodMap[module][functionToken]; - @class = pair.Key; - return pair.Value; + lock (Protection) + { + var module = CoverageSession.Modules + .FirstOrDefault(x => x.Aliases.Any(path => path.Equals(modulePath, StringComparison.InvariantCultureIgnoreCase))); + if (module == null) + return null; + if (!_moduleMethodMap[module].ContainsKey(functionToken)) return null; + var pair = _moduleMethodMap[module][functionToken]; + @class = pair.Key; + return pair.Value; + } } /// @@ -545,7 +471,7 @@ public void SaveVisitData(byte[] data) { if (!InstrumentationPoint.AddVisitCount(spid, _trackedMethodId)) { - _logger.ErrorFormat("Failed to add a visit to {0} with tracking method {1}. Max point count is {2}", + _logger.ErrorFormat("Failed to add a visit to {0} with tracking method {1}. Max point count is {2}", spid, _trackedMethodId, InstrumentationPoint.Count); } } @@ -567,22 +493,369 @@ public void SaveVisitData(byte[] data) /// public bool GetTrackingMethod(string modulePath, string assemblyName, int functionToken, out uint uniqueId) { - uniqueId = 0; - foreach (var module in CoverageSession.Modules - .Where(x => x.TrackedMethods != null) - .Where(x => x.Aliases.Contains(modulePath))) + lock (Protection) { - foreach (var trackedMethod in module.TrackedMethods) + uniqueId = 0; + foreach (var module in CoverageSession.Modules + .Where(x => x.TrackedMethods != null) + .Where(x => x.Aliases.Contains(modulePath))) { - if (trackedMethod.MetadataToken == functionToken) + foreach (var trackedMethod in module.TrackedMethods) { - uniqueId = trackedMethod.UniqueId; - return true; + if (trackedMethod.MetadataToken == functionToken) + { + uniqueId = trackedMethod.UniqueId; + return true; + } } } } - return false; } - } -} \ No newline at end of file + + // static readonly empty collections, saves creation time of new empty ones + // do not modify when referenced/attached to parent + private static readonly SequencePoint[] emptySeqPoints = new SequencePoint[0]; + private static readonly BranchPoint[] emptyBranchPoints = new BranchPoint[0]; + private static readonly List emptyBranchList = new List(0); + + private void TransformSequences() { + + var sessionModulesQuery = CoverageSession.Modules.Where(@module => !@module.ShouldSerializeSkippedDueTo()); + foreach(var module in sessionModulesQuery) { + + // module sources + var sourceRepository = new SourceRepository(); + + // Queries + var moduleClassesQuery = (module.Classes ?? new Class[0]).Where(x => !x.ShouldSerializeSkippedDueTo()); + var moduleMethodsQuery = moduleClassesQuery.SelectMany(@class => (@class.Methods ?? new Method[0])).Where(x => !x.ShouldSerializeSkippedDueTo()); + var methods = new ReadOnlyCollection(moduleMethodsQuery.ToArray()); + + #region Step 0: Collect Module Files (FileID/FullPath/TextSource) + + #endregion + + #region Step 1: Prepare sequences for transformations + TransformSequences_Initialize (methods); + TransformSequences_AddSources (module, methods, sourceRepository); + TransformSequences_JoinWithBranches (methods); + TransformSequences_RemoveBranchesOutOfOffset (methods, sourceRepository); + TransformSequences_NormalizeBranches (methods); + #endregion + + #region step 2: Transformations + //TransformSequences_RemoveUnvisitedDuplicates (methods); + #endregion + } + } + + static void TransformSequences_Initialize (ReadOnlyCollection methods) + { + foreach (var method in methods) { + #region Cleanup + // remove nulls + if (method.SequencePoints == null) + method.SequencePoints = emptySeqPoints; + if (method.BranchPoints == null) + method.BranchPoints = emptyBranchPoints; + // No sequences in method, but branches present? => remove branches + if (method.SequencePoints.Length == 0 && method.BranchPoints.Length != 0) { + method.BranchPoints = emptyBranchPoints; + } + #endregion + } + } + + static void TransformSequences_AddSources (Module module, ReadOnlyCollection methods, IDictionary sourceRepository) + { + // Dictionary with stored source file names per module + var filesDictionary = new Dictionary(); + + foreach (var file in (module.Files ?? new File[0]). + Where (file => !String.IsNullOrWhiteSpace(file.FullPath) + && !filesDictionary.ContainsKey(file.FullPath))) + { + var source = CodeCoverageStringTextSource.GetSource(file.FullPath); + if (source != null) sourceRepository.Add (file.UniqueId, source); + filesDictionary.Add(file.FullPath, file.UniqueId); + } + + foreach (var method in methods) { + #region Add file references + if (method.SequencePoints.Length != 0) + MapFileReferences(method.SequencePoints, filesDictionary); + if (method.BranchPoints.Length != 0) + MapFileReferences(method.BranchPoints, filesDictionary); + #endregion + } + } + + static void TransformSequences_JoinWithBranches (ReadOnlyCollection methods) + { + foreach (var method in methods) { + #region Join BranchPoints children to SequencePoint parent + if (method.SequencePoints.Length != 0 && method.BranchPoints.Length != 0) { + // Quick match branches to sequence using SP&BP sort order by IL offset + // SP & BP are sorted by offset and code below expect both SP & BP to be sorted by offset + // ATTN: Sorted again to prevent future bugs if order of SP & BP is changed! + method.SequencePoints = method.SequencePoints.OrderBy(sp => sp.Offset).ToArray(); + method.BranchPoints = method.BranchPoints.OrderBy(bp => bp.Offset).ToArray(); + // Use stack because Stack.Pop is constant time + var branchStack = new Stack(method.BranchPoints); + // Join offset matching BranchPoints with SequencePoint "parent" + // Exclude all branches where BranchPoint.Offset < first method.SequencePoints.Offset + // Reverse() starts loop from highest offset to lowest + foreach (SequencePoint spParent in method.SequencePoints.Reverse()) { + // create branchPoints "child" list + spParent.BranchPoints = new List(); + // if BranchPoint.Offset is >= SequencePoint.Offset + // then move BranchPoint from stack to "child" list (Pop/Add) + while (branchStack.Count != 0 && branchStack.Peek().Offset >= spParent.Offset) { + spParent.BranchPoints.Add(branchStack.Pop()); + } + } + // clear the stack + branchStack.Clear(); + } + #endregion + } + } + + static void TransformSequences_RemoveBranchesOutOfOffset (ReadOnlyCollection methods, SourceRepository sourceRepository) + { + foreach (var method in methods) { + #region Use Offset To Remove Compiler Generated Branches + if (method.FileRef != null) { + long startOffset = long.MinValue; + long finalOffset = long.MaxValue; + CodeCoverageStringTextSource source = sourceRepository.getCodeCoverageStringTextSource(method.FileRef.UniqueId); + if (source != null && source.FileType == FileType.CSharp) { + var sourceLineOrderedSps = method.SequencePoints.OrderBy(sp => sp.StartLine).ThenBy(sp => sp.StartColumn).Where(sp => sp.FileId == method.FileRef.UniqueId).ToArray(); + if (sourceLineOrderedSps.Length >= 2) { + // leftBrace.sp, any.sp, rightBrace.sp || method.sp; leftBrace.sp, rightBrace.sp + // method { + if (method.MethodPoint == sourceLineOrderedSps[0] && sourceRepository.isLeftBraceSequencePoint(sourceLineOrderedSps[1])) { + startOffset = sourceLineOrderedSps[1].Offset; + //sourceLineOrderedSps[1].BranchPoints = emptyBranchList; + } + // getter/setter/static-method { + else if (sourceRepository.isLeftBraceSequencePoint(sourceLineOrderedSps[0])) { + startOffset = sourceLineOrderedSps[0].Offset; + //sourceLineOrderedSps[0].BranchPoints = emptyBranchList; + } + if (sourceRepository.isRightBraceSequencePoint(sourceLineOrderedSps.Last())) { + finalOffset = sourceLineOrderedSps.Last().Offset; + } + } + } + if (startOffset != long.MinValue || finalOffset != long.MaxValue) { + // doRemoveBranches where .Offset <= startOffset"{" or finalOffset"}" <= .Offset + // this will exclude "{" "}" compiler generated branches and ccrewrite Code Contract's + foreach (var sp in method.SequencePoints) { + if (sp != null && sp.BranchPoints != null && sp.BranchPoints.Count != 0 && sp.FileId == method.FileRef.UniqueId) { + if (sp.Offset <= startOffset || sp.Offset >= finalOffset) { + sp.BranchPoints = emptyBranchList; + } + } + } + } + } + #endregion + } + } + + static void TransformSequences_NormalizeBranches (ReadOnlyCollection methods) + { + foreach (var method in methods) { + #region Merge Branch-Exits for each Sequence + // Collection of validBranchPoints (child/connected to parent SequencePoint) + var validBranchPoints = new List(); + var branchExits = new Dictionary(); + foreach (var sp in method.SequencePoints) { + // SequencePoint has branches attached? + if (sp.BranchPoints != null && sp.BranchPoints.Count != 0) { + // Merge sp.BranchPoints using EndOffset as branchExits key + branchExits.Clear(); + foreach (var branchPoint in sp.BranchPoints) { + if (!branchExits.ContainsKey(branchPoint.EndOffset)) { + branchExits[branchPoint.EndOffset] = branchPoint; + // insert branch + } else { + branchExits[branchPoint.EndOffset].VisitCount += branchPoint.VisitCount; + // update branch + } + } + // Update SequencePoint counters + sp.BranchExitsCount = 0; + sp.BranchExitsVisit = 0; + foreach (var branchPoint in branchExits.Values) { + sp.BranchExitsCount += 1; + sp.BranchExitsVisit += branchPoint.VisitCount == 0 ? 0 : 1; + } + // Add to validBranchPoints + validBranchPoints.AddRange(sp.BranchPoints); + sp.BranchPoints = emptyBranchList; + // clear + } + } + // Replace original method branchPoints with valid (filtered and joined) branches. + // Order is Required by FilePersistanceTest because it does not sets .Offset. + // (Order by UniqueSequencePoint is equal to order by .Offset when .Offset is set) + method.BranchPoints = validBranchPoints.OrderBy(bp => bp.UniqueSequencePoint).ToArray(); + #endregion + } + } + + static void TransformSequences_RemoveUnvisitedDuplicates (ReadOnlyCollection methods) + { + #region ToDo + /* Problems: + * 1) Compiler can duplicate sequence point (found in DBCL project) + * Solution: + * Remove unvisited duplicate? + * + * 2) Compiler can move SequencePoint into compiler generated method + * Solution? + * Identify compiler generated methods + * Match each with user method + * Move SequencePoints & branches into user method + * + */ + #endregion + + #region Examples + /* Duplicate SequencePoint Example + Generated Method * + * + * 100663434 + <_SetItems>b__b * System.Boolean DD.Collections.BitSetArray::<_SetItems>b__b(System.Int32) + * + * + Duplicate SP! * + * + * + * + * + * + Generated Method * + * + * 100663435 + <_SetItems>b__b_0* System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32) + * + * + Duplicate SP! * + * + * + * + * + * + User Method * + * + * 100663375 + * System.Void DD.Collections.BitSetArray::_SetItems(System.Collections.Generic.IEnumerable`1<System.Int32>) + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + #endregion + + //var generatedMethods = new List(); + //var userCodedMethods = new List(); + var lostSequencePoints = new Dictionary(); + //ILog TempLogger = LogManager.GetLogger("OpenCover"); + // Extract from generated methods (sp.BranchPoints are collected&connected) + foreach (var method in @methods) { + if (!Object.ReferenceEquals(method, null) && method.SequencePoints.Length != 0) { + if (method.isGenerated) { + //TempLogger.Info(getMethodName(method)); + //generatedMethods.Add(method); + foreach (var sp in method.SequencePoints) { + if (!Object.ReferenceEquals(sp, null) && sp.VisitCount == 0) { + lostSequencePoints.Add(sp, method); + } + } + } else { + //userCodedMethods.Add(method); + } + } + } + //TempLogger.Warn("lostSequencePoints.Count " + lostSequencePoints.Count); + if (lostSequencePoints.Count != 0) { + // Remove lost if is duplicate + foreach (var method in @methods) { + if (!Object.ReferenceEquals(method, null)) { + foreach (var sp in method.SequencePoints) { + if (!Object.ReferenceEquals(sp, null) && lostSequencePoints.ContainsKey(sp)) { + var cleanSequencePoints = new List(); + foreach (var spGenerated in lostSequencePoints[sp].SequencePoints) { + if (!spGenerated.Equals(sp)) { + cleanSequencePoints.Add(spGenerated); + } else { + //TempLogger.Warn("Sequence skipped, line: " + spGenerated.StartLine); + } + } + lostSequencePoints[sp].SequencePoints = cleanSequencePoints.ToArray(); + } + } + } + } + } + } + + } // Class +} // Namespace diff --git a/main/OpenCover.Framework/Persistance/FilePersistance.cs b/main/OpenCover.Framework/Persistance/FilePersistance.cs index ffc063810..f1c3cb2c8 100644 --- a/main/OpenCover.Framework/Persistance/FilePersistance.cs +++ b/main/OpenCover.Framework/Persistance/FilePersistance.cs @@ -68,6 +68,9 @@ private void LoadCoverageFile() } } + /// + /// we are done and the data needs one last clean up + /// public override void Commit() { _logger.Info("Committing..."); diff --git a/main/OpenCover.Framework/Strategy/TrackedMethodStrategyManager.cs b/main/OpenCover.Framework/Strategy/TrackedMethodStrategyManager.cs index a5677b87e..a50678ab8 100644 --- a/main/OpenCover.Framework/Strategy/TrackedMethodStrategyManager.cs +++ b/main/OpenCover.Framework/Strategy/TrackedMethodStrategyManager.cs @@ -66,6 +66,12 @@ public TrackedMethodStrategyManager() } private int _methodId; + + /// + /// Get the tracked methods for the target assembly + /// + /// + /// public TrackedMethod[] GetTrackedMethods(string assembly) { var methods = _proxy.GetTrackedMethods(assembly); @@ -76,6 +82,10 @@ public TrackedMethod[] GetTrackedMethods(string assembly) return methods; } + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + /// 2 public void Dispose() { _proxy = null; diff --git a/main/OpenCover.Framework/Symbols/CecilSymbolManager.cs b/main/OpenCover.Framework/Symbols/CecilSymbolManager.cs index c295906f3..c2051c3f5 100644 --- a/main/OpenCover.Framework/Symbols/CecilSymbolManager.cs +++ b/main/OpenCover.Framework/Symbols/CecilSymbolManager.cs @@ -389,6 +389,7 @@ private void GetSequencePointsForToken(int token, List list) } } + private static Regex isMovenext = new Regex(@"\<[^\s|>]+\>\w__\w(\w)?::MoveNext\(\)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture); private void GetBranchPointsForToken(int token, List list) { var methodDefinition = GetMethodDefinition(token); @@ -399,7 +400,7 @@ private void GetBranchPointsForToken(int token, List list) var instructions = methodDefinition.SafeGetMethodBody().Instructions; // if method is a generated MoveNext skip first branch (could be a switch or a branch) - var skipFirstBranch = Regex.IsMatch(methodDefinition.FullName, @"\<.+\>d__\d+::MoveNext\(\)$"); + var skipFirstBranch = isMovenext.IsMatch(methodDefinition.FullName); foreach (var instruction in instructions.Where(instruction => instruction.OpCode.FlowControl == FlowControl.Cond_Branch)) { diff --git a/main/OpenCover.Framework/Utility/CodeCoverageStringTextSource.cs b/main/OpenCover.Framework/Utility/CodeCoverageStringTextSource.cs new file mode 100644 index 000000000..df8e5e6e1 --- /dev/null +++ b/main/OpenCover.Framework/Utility/CodeCoverageStringTextSource.cs @@ -0,0 +1,287 @@ +// Copyright (c) https://github.com/ddur +// This code is distributed under MIT license + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using OpenCover.Framework.Model; + +namespace OpenCover.Framework.Utility +{ + /// + /// FileType enum + /// + public enum FileType : byte { + /// + /// Unsupported file extension + /// + Unsupported, + + /// + /// File extension is ".cs" + /// + CSharp, + + /// + /// File extension is ".vb" + /// + VBasic + } + /// StringTextSource (ReadOnly) + /// Line and column counting starts at 1. + /// + public class CodeCoverageStringTextSource + { + /// + /// File Type by file name extension + /// + public FileType FileType = FileType.Unsupported; + private readonly string textSource; + private struct lineInfo { + public int Offset; + public int Length; + } + private readonly lineInfo[] lines; + /// + /// Constructor + /// + /// + public CodeCoverageStringTextSource(string source) + { + this.textSource = source; + + lineInfo line; + var lineInfoList = new List(); + int offset = 0; + int counter = 0; + bool newLine = false; + bool cr = false; + bool lf = false; + + foreach ( ushort ch in textSource ) { + switch (ch) { + case 0xD: + if (lf||cr) { + newLine = true; // cr after cr|lf + } else { + cr = true; // cr found + } + break; + case 0xA: + if (lf) { + newLine = true; // lf after lf + } else { + lf = true; // lf found + } + break; + default: + if (cr||lf) { + newLine = true; // any non-line-end char after any line-end + } + break; + } + if (newLine) { // newLine detected - add line + line = new lineInfo(); + line.Offset = offset; + line.Length = counter - offset; + lineInfoList.Add(line); + offset = counter; + cr = false; + lf = false; + newLine = false; + } + ++counter; + } + + // Add last line + line = new lineInfo(); + line.Offset = offset; + line.Length = counter - offset; + lineInfoList.Add(line); + + // Store to readonly field + lines = lineInfoList.ToArray(); + } + + /// Return text/source using SequencePoint line/col info + /// + /// + /// + public string GetText(SequencePoint sp) { + return this.GetText(sp.StartLine, sp.StartColumn, sp.EndLine, sp.EndColumn ); + } + + /// Return text at Line/Column/EndLine/EndColumn position + /// Line and Column counting starts at 1. + /// + /// + /// + /// + /// + /// + public string GetText(int Line, int Column, int EndLine, int EndColumn) { + + var text = new StringBuilder(); + string line; + bool argOutOfRange; + + if (Line==EndLine) { + + #region One-Line request + line = GetLine(Line); + + //Debug.Assert(!(Column < 1), "Column < 1"); + //Debug.Assert(!(Column > EndColumn), "Column > EndColumn"); + //Debug.Assert(!(EndColumn > line.Length + 1), string.Format ("Single Line EndColumn({0}) > line.Length({1})",EndColumn, line.Length )); + //Debug.Assert(!(EndColumn > line.Length + 1), line); + + argOutOfRange = Column < 1 + || Column > EndColumn + || EndColumn > line.Length; + if (!argOutOfRange) { + text.Append(line.Substring(Column-1,EndColumn-Column)); + } + #endregion + + } else if (Line line.Length), string.Format ("First MultiLine EndColumn({0}) > line.Length({1})",EndColumn, line.Length )); + + argOutOfRange = Column < 1 + || Column > line.Length; + if (!argOutOfRange) { + text.Append(line.Substring(Column-1)); + } + #endregion + + #region More than two lines + for ( int lineIndex = Line+1; lineIndex < EndLine; lineIndex++ ) { + text.Append ( GetLine ( lineIndex ) ); + } + #endregion + + #region Last line + line = GetLine(EndLine); + + //Debug.Assert(!(EndColumn < 1), "EndColumn < 1"); + //Debug.Assert(!(EndColumn > line.Length), string.Format ("Last MultiLine EndColumn({0}) > line.Length({1})",EndColumn, line.Length )); + + argOutOfRange = EndColumn < 1 + || EndColumn > line.Length; + if (!argOutOfRange) { + text.Append(line.Substring(0,EndColumn)); + } + #endregion + + #endregion + + } else { + //Debug.Fail("Line > EndLine"); + } + return text.ToString(); + } + + /// + /// Return number of lines in source + /// + public int LinesCount { + get { + return lines.Length; + } + } + + /// Return SequencePoint enumerated line + /// + /// + /// + public string GetLine ( int LineNo ) { + + string retString = String.Empty; + + if ( LineNo > 0 && LineNo <= lines.Length ) { + lineInfo lineInfo = lines[LineNo-1]; + retString = textSource.Substring(lineInfo.Offset, lineInfo.Length); + } else { + //Debug.Fail( "Line number out of range" ); + } + + return retString; + } + + /// + /// + /// + /// + /// + /// + public static string IndentTabs ( string ToIndent, int TabSize ) { + + string retString = ToIndent; + if ( ToIndent.Contains ( "\t" ) ) { + int counter = 0; + int remains = 0; + int repeat = 0; + char prevChar = char.MinValue; + var indented = new StringBuilder(); + foreach ( char currChar in ToIndent ) { + if ( currChar == '\t' ) { + remains = counter % TabSize; + repeat = remains == 0 ? TabSize : remains; + indented.Append( ' ', repeat ); + } else { + indented.Append ( currChar, 1 ); + if ( char.IsLowSurrogate(currChar) + && char.IsHighSurrogate(prevChar) + ) { --counter; } + } + prevChar = currChar; + ++counter; + } + retString = indented.ToString(); + } + return retString; + } + + /// + /// Get line-parsed source from file name + /// + /// + /// + public static CodeCoverageStringTextSource GetSource(string filename) { + + var retSource = (CodeCoverageStringTextSource)null; + try { + using (Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { + try { + stream.Position = 0; + using (var reader = new StreamReader (stream, Encoding.Default, true)) { + retSource = new CodeCoverageStringTextSource(reader.ReadToEnd()); + switch (Path.GetExtension(filename).ToLowerInvariant()) { + case ".cs": + retSource.FileType = FileType.CSharp; + break; + case ".vb": + retSource.FileType = FileType.VBasic; + break; + default: + retSource.FileType = FileType.Unsupported; + break; + } + } + } catch (Exception) {} + } + } catch (Exception) {} + + return retSource; + } + + } +} diff --git a/main/OpenCover.Framework/Utility/PerfCounters.cs b/main/OpenCover.Framework/Utility/PerfCounters.cs index e1774b247..a8feb4832 100644 --- a/main/OpenCover.Framework/Utility/PerfCounters.cs +++ b/main/OpenCover.Framework/Utility/PerfCounters.cs @@ -9,15 +9,19 @@ namespace OpenCover.Framework.Utility public class PerfCounters : IPerfCounters { private PerformanceCounter _memoryQueue; - private PerformanceCounter _queueThrougput; + private PerformanceCounter _queueThroughput; /// /// get the current queue size /// public int CurrentMemoryQueueSize { set { _memoryQueue.RawValue = value; } } + + /// + /// Increment the block size + /// public void IncrementBlocksReceived() { - _queueThrougput.RawValue += 1; + _queueThroughput.RawValue += 1; } /// @@ -50,13 +54,16 @@ private void CreateCounters() PerformanceCounterCategoryType.SingleInstance, counters); _memoryQueue = new PerformanceCounter(CategoryName, MemoryQueue, false) { RawValue = 0 }; - _queueThrougput = new PerformanceCounter(CategoryName, QueueThroughput, false) { RawValue = 0 }; + _queueThroughput = new PerformanceCounter(CategoryName, QueueThroughput, false) { RawValue = 0 }; } + /// + /// Reset all counters + /// public void ResetCounters() { _memoryQueue.RawValue = 0; - _queueThrougput.RawValue = 0; + _queueThroughput.RawValue = 0; } } @@ -69,11 +76,19 @@ public class NullPerfCounter : IPerfCounters /// /// A null performance counters implementation /// + // ReSharper disable once UnusedAutoPropertyAccessor.Local public int CurrentMemoryQueueSize { set; private get; } + + /// + /// Increment the number of blocks received + /// public void IncrementBlocksReceived() { } + /// + /// Reset all counters + /// public void ResetCounters() { } diff --git a/main/OpenCover.Framework/Utility/SourceRepository.cs b/main/OpenCover.Framework/Utility/SourceRepository.cs new file mode 100644 index 000000000..bf2eee46e --- /dev/null +++ b/main/OpenCover.Framework/Utility/SourceRepository.cs @@ -0,0 +1,229 @@ +/* + * Created by SharpDevelop. + * User: ddur + * Date: 23.12.2015. + * Time: 14:17 + * + * Copyright https://github.com/ddur + * This source code is released under the MIT License; see the accompanying license file. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using OpenCover.Framework.Model; + +namespace OpenCover.Framework.Utility +{ + /// + /// Collection of CodeCoverageStringTextSources + /// + public class SourceRepository : IDictionary + { + private readonly IDictionary repo = new Dictionary(); + /// + /// + /// + public SourceRepository() + { + } + + private uint fileID_cache = 0; + private CodeCoverageStringTextSource textSource_cache = null; + + /// + /// Get string Text Source by FileID + /// + /// + /// + public CodeCoverageStringTextSource getCodeCoverageStringTextSource (uint fileId) { + CodeCoverageStringTextSource source = null; + if (fileId != 0) { + if (fileID_cache == fileId) { + source = textSource_cache; + } else { + this.TryGetValue (fileId, out source); + if (source != null) { + fileID_cache = fileId; + textSource_cache = source; + } + } + } + return source; + } + + /// + /// SequencePoint source-string if available, else empty string + /// + /// SequencePoint + /// string + public string getSequencePointText (SequencePoint sp) { + if (sp != null) { + CodeCoverageStringTextSource source = this.getCodeCoverageStringTextSource (sp.FileId); + return source != null ? source.GetText(sp) : ""; + } + return ""; + } + /// + /// True if SequencePoint source-string == "{" + /// + /// + /// + public bool isLeftBraceSequencePoint (SequencePoint sp) { + return sp.isSingleCharSequencePoint && this.getSequencePointText(sp) == "{"; + } + /// + /// True if SequencePoint source-string == "}" + /// + /// + /// + public bool isRightBraceSequencePoint (SequencePoint sp) { + return sp.isSingleCharSequencePoint && this.getSequencePointText(sp) == "}"; + } + + #region IDictionary implementation + /// + /// + /// + /// + /// + public bool ContainsKey(uint key) + { + return repo.ContainsKey(key); + } + /// + /// + /// + /// + /// + public void Add(uint key, CodeCoverageStringTextSource value) + { + repo.Add(key, value); + } + /// + /// + /// + /// + /// + public bool Remove(uint key) + { + return repo.Remove(key); + } + /// + /// + /// + /// + /// + /// + public bool TryGetValue(uint key, out CodeCoverageStringTextSource value) + { + return repo.TryGetValue(key, out value); + } + /// + /// + /// + public CodeCoverageStringTextSource this[uint key] { + get { + return repo[key]; + } + set { + repo[key] = value; + } + } + /// + /// + /// + public ICollection Keys { + get { + return repo.Keys; + } + } + /// + /// + /// + public ICollection Values { + get { + return repo.Values; + } + } + #endregion + + #region ICollection implementation + /// + /// + /// + /// + public void Add(KeyValuePair item) + { + repo.Add(item); + } + /// + /// + /// + public void Clear() + { + repo.Clear(); + } + /// + /// + /// + /// + /// + public bool Contains(KeyValuePair item) + { + return repo.Contains(item); + } + /// + /// + /// + /// + /// + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + repo.CopyTo(array, arrayIndex); + } + /// + /// + /// + /// + /// + public bool Remove(KeyValuePair item) + { + return repo.Remove(item); + } + /// + /// + /// + public int Count { + get { + return repo.Count; + } + } + /// + /// + /// + public bool IsReadOnly { + get { + return repo.IsReadOnly; + } + } + #endregion + + #region IEnumerable implementation + /// + /// + /// + /// + public IEnumerator> GetEnumerator() + { + return repo.GetEnumerator(); + } + #endregion + + #region IEnumerable implementation + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)repo).GetEnumerator(); + } + #endregion + } +} diff --git a/main/OpenCover.Framework/Utility/ThreadHelper.cs b/main/OpenCover.Framework/Utility/ThreadHelper.cs new file mode 100644 index 000000000..9643ea1bf --- /dev/null +++ b/main/OpenCover.Framework/Utility/ThreadHelper.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace OpenCover.Framework.Utility +{ + internal static class ThreadHelper + { + public static void YieldOrSleep(int millisecondsInTimeout) + { + if (!Thread.Yield()) + { + Thread.Sleep(millisecondsInTimeout); + } + } + + public static void YieldOrSleep(TimeSpan timespan) + { + if (!Thread.Yield()) + { + Thread.Sleep(timespan); + } + } + } +} diff --git a/main/OpenCover.Installer/Components.wxs b/main/OpenCover.Installer/Components.wxs index 5eeece707..1f848c134 100644 --- a/main/OpenCover.Installer/Components.wxs +++ b/main/OpenCover.Installer/Components.wxs @@ -16,12 +16,15 @@ + + + @@ -43,11 +46,6 @@ - - - - - @@ -87,9 +85,7 @@ --> - - - + @@ -105,9 +101,7 @@ --> - - - + diff --git a/main/OpenCover.Installer/Product.wxs b/main/OpenCover.Installer/Product.wxs index c8de0522f..121b8d6d2 100644 --- a/main/OpenCover.Installer/Product.wxs +++ b/main/OpenCover.Installer/Product.wxs @@ -56,20 +56,13 @@ + + - - - - - - - - - diff --git a/main/OpenCover.NugetPackage/OpenCover.nuspec b/main/OpenCover.NugetPackage/OpenCover.nuspec index 0cd4571a6..8ef771177 100644 --- a/main/OpenCover.NugetPackage/OpenCover.nuspec +++ b/main/OpenCover.NugetPackage/OpenCover.nuspec @@ -36,6 +36,7 @@ + diff --git a/main/OpenCover.Profiler/CodeCoverage.cpp b/main/OpenCover.Profiler/CodeCoverage.cpp index 0e7cd679f..1615f895a 100644 --- a/main/OpenCover.Profiler/CodeCoverage.cpp +++ b/main/OpenCover.Profiler/CodeCoverage.cpp @@ -10,7 +10,7 @@ #include "NativeCallback.h" #include "dllmain.h" -CCodeCoverage* CCodeCoverage::g_pProfiler = NULL; +CCodeCoverage* CCodeCoverage::g_pProfiler = nullptr; // CCodeCoverage /// Handle ICorProfilerCallback::Initialize @@ -22,15 +22,15 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::Initialize( } HRESULT CCodeCoverage::OpenCoverInitialise(IUnknown *pICorProfilerInfoUnk){ - ATLTRACE(_T("::OpenCoverInitialise")); + ATLTRACE(_T("::OpenCoverInitialise\n")); OLECHAR szGuid[40]={0}; - int nCount = ::StringFromGUID2(CLSID_CodeCoverage, szGuid, 40); + ::StringFromGUID2(CLSID_CodeCoverage, szGuid, 40); RELTRACE(L" ::Initialize(...) => CLSID == %s", szGuid); //::OutputDebugStringW(szGuid); WCHAR szExeName[MAX_PATH]; - GetModuleFileNameW(NULL, szExeName, MAX_PATH); + GetModuleFileNameW(nullptr, szExeName, MAX_PATH); RELTRACE(L" ::Initialize(...) => EXE = %s", szExeName); WCHAR szModuleName[MAX_PATH]; @@ -38,76 +38,87 @@ HRESULT CCodeCoverage::OpenCoverInitialise(IUnknown *pICorProfilerInfoUnk){ RELTRACE(L" ::Initialize(...) => PROFILER = %s", szModuleName); //::OutputDebugStringW(szModuleName); - if (g_pProfiler!=NULL) - RELTRACE(_T("Another instance of the profiler is running under this process...")); + if (g_pProfiler!=nullptr) + RELTRACE(_T("Another instance of the profiler is running under this process...\n")); m_profilerInfo = pICorProfilerInfoUnk; - if (m_profilerInfo != NULL) ATLTRACE(_T(" ::Initialize (m_profilerInfo OK)")); - if (m_profilerInfo == NULL) return E_FAIL; + if (m_profilerInfo != nullptr) ATLTRACE(_T(" ::Initialize (m_profilerInfo OK)")); + if (m_profilerInfo == nullptr) return E_FAIL; m_profilerInfo2 = pICorProfilerInfoUnk; - if (m_profilerInfo2 != NULL) ATLTRACE(_T(" ::Initialize (m_profilerInfo2 OK)")); - if (m_profilerInfo2 == NULL) return E_FAIL; + if (m_profilerInfo2 != nullptr) ATLTRACE(_T(" ::Initialize (m_profilerInfo2 OK)")); + if (m_profilerInfo2 == nullptr) return E_FAIL; m_profilerInfo3 = pICorProfilerInfoUnk; #ifndef _TOOLSETV71 m_profilerInfo4 = pICorProfilerInfoUnk; #endif ZeroMemory(&m_runtimeVersion, sizeof(m_runtimeVersion)); - if (m_profilerInfo3 != NULL) + if (m_profilerInfo3 != nullptr) { - ATLTRACE(_T(" ::Initialize (m_profilerInfo3 OK)")); + ATLTRACE(_T(" ::Initialize (m_profilerInfo3 OK)\n")); ZeroMemory(&m_runtimeVersion, sizeof(m_runtimeVersion)); - m_profilerInfo3->GetRuntimeInformation(NULL, &m_runtimeType, + m_profilerInfo3->GetRuntimeInformation(nullptr, &m_runtimeType, &m_runtimeVersion.usMajorVersion, &m_runtimeVersion.usMinorVersion, &m_runtimeVersion.usBuildNumber, - &m_runtimeVersion.usRevisionNumber, 0, NULL, NULL); + &m_runtimeVersion.usRevisionNumber, 0, nullptr, nullptr); - ATLTRACE(_T(" ::Initialize (Runtime %d)"), m_runtimeType); + ATLTRACE(_T(" ::Initialize (Runtime %d)\n"), m_runtimeType); } TCHAR key[1024] = {0}; ::GetEnvironmentVariable(_T("OpenCover_Profiler_Key"), key, 1024); - RELTRACE(_T(" ::Initialize(...) => key = %s"), key); + RELTRACE(_T(" ::Initialize(...) => key = %s\n"), key); TCHAR ns[1024] = {0}; ::GetEnvironmentVariable(_T("OpenCover_Profiler_Namespace"), ns, 1024); - ATLTRACE(_T(" ::Initialize(...) => ns = %s"), ns); + ATLTRACE(_T(" ::Initialize(...) => ns = %s\n"), ns); TCHAR instrumentation[1024] = {0}; ::GetEnvironmentVariable(_T("OpenCover_Profiler_Instrumentation"), instrumentation, 1024); - ATLTRACE(_T(" ::Initialize(...) => instrumentation = %s"), instrumentation); + ATLTRACE(_T(" ::Initialize(...) => instrumentation = %s\n"), instrumentation); TCHAR threshold[1024] = {0}; ::GetEnvironmentVariable(_T("OpenCover_Profiler_Threshold"), threshold, 1024); - m_threshold = _tcstoul(threshold, NULL, 10); - ATLTRACE(_T(" ::Initialize(...) => threshold = %ul"), m_threshold); + m_threshold = _tcstoul(threshold, nullptr, 10); + ATLTRACE(_T(" ::Initialize(...) => threshold = %ul\n"), m_threshold); TCHAR tracebyTest[1024] = {0}; ::GetEnvironmentVariable(_T("OpenCover_Profiler_TraceByTest"), tracebyTest, 1024); m_tracingEnabled = _tcslen(tracebyTest) != 0; - ATLTRACE(_T(" ::Initialize(...) => tracingEnabled = %s (%s)"), m_tracingEnabled ? _T("true") : _T("false"), tracebyTest); - + ATLTRACE(_T(" ::Initialize(...) => tracingEnabled = %s (%s)"), m_tracingEnabled ? _T("true") : _T("false\n"), tracebyTest); + + TCHAR shortwait[1024] = { 0 }; + if (::GetEnvironmentVariable(_T("OpenCover_Profiler_ShortWait"), shortwait, 1024) > 0) { + _shortwait = _tcstoul(shortwait, nullptr, 10); + if (_shortwait < 10000) + _shortwait = 10000; + if (_shortwait > 60000) + _shortwait = 60000; + ATLTRACE(_T(" ::Initialize(...) => shortwait = %ul"), _shortwait); + } m_useOldStyle = (tstring(instrumentation) == _T("oldSchool")); - if (!m_host.Initialise(key, ns, szExeName)) + _host = std::make_shared(ProfilerCommunication(_shortwait)); + + if (!_host->Initialise(key, ns, szExeName)) { - RELTRACE(_T(" ::Initialize => Profiler will not run for this process.")); + RELTRACE(_T(" ::Initialize => Profiler will not run for this process.\n")); return E_FAIL; } OpenCoverSupportInitialize(pICorProfilerInfoUnk); - if (m_chainedProfiler == NULL){ + if (m_chainedProfiler == nullptr){ DWORD dwMask = AppendProfilerEventMask(0); COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->SetEventMask(dwMask), _T(" ::Initialize(...) => SetEventMask => 0x%X")); } - if(m_profilerInfo3 != NULL) + if(m_profilerInfo3 != nullptr) { COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo3->SetFunctionIDMapper2(FunctionMapper2, this), _T(" ::Initialize(...) => SetFunctionIDMapper2 => 0x%X")); @@ -125,7 +136,7 @@ HRESULT CCodeCoverage::OpenCoverInitialise(IUnknown *pICorProfilerInfoUnk){ _FunctionEnter2, _FunctionLeave2, _FunctionTailcall2), _T(" ::Initialize(...) => SetEnterLeaveFunctionHooks2 => 0x%X")); #endif - RELTRACE(_T("::Initialize - Done!")); + RELTRACE(_T("::Initialize - Done!\n")); return S_OK; } @@ -146,9 +157,9 @@ DWORD CCodeCoverage::AppendProfilerEventMask(DWORD currentEventMask) dwMask |= COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST; // Disables security transparency checks that are normally done during just-in-time (JIT) compilation and class loading for full-trust assemblies. This can make some instrumentation easier to perform. #ifndef _TOOLSETV71 - if (m_profilerInfo4 != NULL) + if (m_profilerInfo4 != nullptr) { - ATLTRACE(_T(" ::Initialize (m_profilerInfo4 OK)")); + ATLTRACE(_T(" ::Initialize (m_profilerInfo4 OK)\n")); dwMask |= COR_PRF_DISABLE_ALL_NGEN_IMAGES; } #endif @@ -161,17 +172,17 @@ DWORD CCodeCoverage::AppendProfilerEventMask(DWORD currentEventMask) /// Handle ICorProfilerCallback::Shutdown HRESULT STDMETHODCALLTYPE CCodeCoverage::Shutdown( void) { - RELTRACE(_T("::Shutdown - Starting")); + RELTRACE(_T("::Shutdown - Starting\n")); - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) m_chainedProfiler->Shutdown(); - m_host.CloseChannel(m_tracingEnabled); + _host->CloseChannel(m_tracingEnabled); WCHAR szExeName[MAX_PATH]; - GetModuleFileNameW(NULL, szExeName, MAX_PATH); - RELTRACE(_T("::Shutdown - Nothing left to do but return S_OK(%s)"), szExeName); - g_pProfiler = NULL; + GetModuleFileNameW(nullptr, szExeName, MAX_PATH); + RELTRACE(_T("::Shutdown - Nothing left to do but return S_OK(%s)\n"), szExeName); + g_pProfiler = nullptr; return S_OK; } @@ -197,10 +208,10 @@ void __fastcall CCodeCoverage::AddVisitPoint(ULONG uniqueId) } if (m_tracingEnabled){ - m_host.AddVisitPoint(uniqueId); + _host->AddVisitPoint(uniqueId); } else { - m_host.AddVisitPointToThreadBuffer(uniqueId, IT_VisitPoint); + _host->AddVisitPointToThreadBuffer(uniqueId, IT_VisitPoint); } } @@ -215,7 +226,7 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ModuleLoadFinished( /* [in] */ ModuleID moduleId, /* [in] */ HRESULT hrStatus) { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) m_chainedProfiler->ModuleLoadFinished(moduleId, hrStatus); return RegisterCuckoos(moduleId); @@ -228,19 +239,19 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ModuleAttachedToAssembly( /* [in] */ ModuleID moduleId, /* [in] */ AssemblyID assemblyId) { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) m_chainedProfiler->ModuleAttachedToAssembly(moduleId, assemblyId); std::wstring modulePath = GetModulePath(moduleId); std::wstring assemblyName = GetAssemblyName(assemblyId); - /*ATLTRACE(_T("::ModuleAttachedToAssembly(...) => (%X => %s, %X => %s)"), + /*ATLTRACE(_T("::ModuleAttachedToAssembly(...) => (%X => %s, %X => %s)\n"), moduleId, W2CT(modulePath.c_str()), assemblyId, W2CT(assemblyName.c_str()));*/ - m_allowModules[modulePath] = m_host.TrackAssembly((LPWSTR)modulePath.c_str(), (LPWSTR)assemblyName.c_str()); + m_allowModules[modulePath] = _host->TrackAssembly(const_cast(modulePath.c_str()), const_cast(assemblyName.c_str())); m_allowModulesAssemblyMap[modulePath] = assemblyName; if (m_allowModules[modulePath]){ - ATLTRACE(_T("::ModuleAttachedToAssembly(...) => (%X => %s, %X => %s)"), + ATLTRACE(_T("::ModuleAttachedToAssembly(...) => (%X => %s, %X => %s)\n"), moduleId, W2CT(modulePath.c_str()), assemblyId, W2CT(assemblyName.c_str())); } @@ -268,27 +279,25 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::JITCompilationStarted( if (m_allowModules[modulePath]) { - ATLTRACE(_T("::JITCompilationStarted(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(modulePath.c_str())); + ATLTRACE(_T("::JITCompilationStarted(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(modulePath.c_str())); std::vector seqPoints; std::vector brPoints; - if (m_host.GetPoints(functionToken, (LPWSTR)modulePath.c_str(), - (LPWSTR)m_allowModulesAssemblyMap[modulePath].c_str(), seqPoints, brPoints)) + if (_host->GetPoints(functionToken, const_cast(modulePath.c_str()), + const_cast(m_allowModulesAssemblyMap[modulePath].c_str()), seqPoints, brPoints)) { if (seqPoints.size() != 0) { - LPCBYTE pMethodHeader = NULL; + IMAGE_COR_ILMETHOD* pMethodHeader = nullptr; ULONG iMethodSize = 0; - COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->GetILFunctionBody(moduleId, functionToken, &pMethodHeader, &iMethodSize), + COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->GetILFunctionBody(moduleId, functionToken, (LPCBYTE*)&pMethodHeader, &iMethodSize), _T(" ::JITCompilationStarted(...) => GetILFunctionBody => 0x%X")); - IMAGE_COR_ILMETHOD* pMethod = (IMAGE_COR_ILMETHOD*)pMethodHeader; - - Method instumentedMethod(pMethod); + Method instumentedMethod(pMethodHeader); instumentedMethod.IncrementStackSize(2); - ATLTRACE(_T("::JITCompilationStarted(...) => Instrumenting...")); + ATLTRACE(_T("::JITCompilationStarted(...) => Instrumenting...\n")); //seqPoints.clear(); //brPoints.clear(); @@ -301,13 +310,13 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::JITCompilationStarted( COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->GetILFunctionBodyAllocator(moduleId, &methodMalloc), _T(" ::JITCompilationStarted(...) => GetILFunctionBodyAllocator=> 0x%X")); - IMAGE_COR_ILMETHOD* pNewMethod = (IMAGE_COR_ILMETHOD*)methodMalloc->Alloc(instumentedMethod.GetMethodSize()); + auto pNewMethod = static_cast(methodMalloc->Alloc(instumentedMethod.GetMethodSize())); instumentedMethod.WriteMethod(pNewMethod); COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->SetILFunctionBody(moduleId, functionToken, (LPCBYTE)pNewMethod), _T(" ::JITCompilationStarted(...) => SetILFunctionBody => 0x%X")); ULONG mapSize = instumentedMethod.GetILMapSize(); - COR_IL_MAP * pMap = (COR_IL_MAP *)CoTaskMemAlloc(mapSize * sizeof(COR_IL_MAP)); + COR_IL_MAP * pMap = static_cast(CoTaskMemAlloc(mapSize * sizeof(COR_IL_MAP))); instumentedMethod.PopulateILMap(mapSize, pMap); COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo2->SetILInstrumentedCodeMap(functionId, TRUE, mapSize, pMap), _T(" ::JITCompilationStarted(...) => SetILInstrumentedCodeMap => 0x%X")); @@ -329,7 +338,7 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::JITCompilationStarted( } } - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->JITCompilationStarted(functionId, fIsSafeToBlock); return S_OK; @@ -343,22 +352,22 @@ void CCodeCoverage::InstrumentMethod(ModuleID moduleId, Method& method, std::ve { if (m_useOldStyle) { - mdSignature pvsig = GetMethodSignatureToken_I4(moduleId); - void(__fastcall *pt)(ULONG) = GetInstrumentPointVisit(); + auto pvsig = GetMethodSignatureToken_I4(moduleId); + auto pt = GetInstrumentPointVisit(); InstructionList instructions; if (seqPoints.size() > 0) CoverageInstrumentation::InsertFunctionCall(instructions, pvsig, (FPTR)pt, seqPoints[0].UniqueId); if (method.IsInstrumented(0, instructions)) return; - CoverageInstrumentation::AddBranchCoverage([pvsig, pt](InstructionList& instructions, ULONG uniqueId)->Instruction* + CoverageInstrumentation::AddBranchCoverage([pvsig, pt](InstructionList& brinstructions, ULONG uniqueId)->Instruction* { - return CoverageInstrumentation::InsertFunctionCall(instructions, pvsig, (FPTR)pt, uniqueId); + return CoverageInstrumentation::InsertFunctionCall(brinstructions, pvsig, (FPTR)pt, uniqueId); }, method, brPoints, seqPoints); - CoverageInstrumentation::AddSequenceCoverage([pvsig, pt](InstructionList& instructions, ULONG uniqueId)->Instruction* + CoverageInstrumentation::AddSequenceCoverage([pvsig, pt](InstructionList& seqinstructions, ULONG uniqueId)->Instruction* { - return CoverageInstrumentation::InsertFunctionCall(instructions, pvsig, (FPTR)pt, uniqueId); + return CoverageInstrumentation::InsertFunctionCall(seqinstructions, pvsig, (FPTR)pt, uniqueId); }, method, seqPoints); } else @@ -370,27 +379,26 @@ void CCodeCoverage::InstrumentMethod(ModuleID moduleId, Method& method, std::ve CoverageInstrumentation::InsertInjectedMethod(instructions, injectedVisitedMethod, seqPoints[0].UniqueId); if (method.IsInstrumented(0, instructions)) return; - CoverageInstrumentation::AddBranchCoverage([injectedVisitedMethod](InstructionList& instructions, ULONG uniqueId)->Instruction* + CoverageInstrumentation::AddBranchCoverage([injectedVisitedMethod](InstructionList& brinstructions, ULONG uniqueId)->Instruction* { - return CoverageInstrumentation::InsertInjectedMethod(instructions, injectedVisitedMethod, uniqueId); + return CoverageInstrumentation::InsertInjectedMethod(brinstructions, injectedVisitedMethod, uniqueId); }, method, brPoints, seqPoints); - CoverageInstrumentation::AddSequenceCoverage([injectedVisitedMethod](InstructionList& instructions, ULONG uniqueId)->Instruction* + CoverageInstrumentation::AddSequenceCoverage([injectedVisitedMethod](InstructionList& seqinstructions, ULONG uniqueId)->Instruction* { - return CoverageInstrumentation::InsertInjectedMethod(instructions, injectedVisitedMethod, uniqueId); + return CoverageInstrumentation::InsertInjectedMethod(seqinstructions, injectedVisitedMethod, uniqueId); }, method, seqPoints); } } HRESULT CCodeCoverage::InstrumentMethodWith(ModuleID moduleId, mdToken functionToken, InstructionList &instructions){ - LPCBYTE pMethodHeader = NULL; + IMAGE_COR_ILMETHOD* pMethodHeader = nullptr; ULONG iMethodSize = 0; - COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo->GetILFunctionBody(moduleId, functionToken, &pMethodHeader, &iMethodSize), + COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo->GetILFunctionBody(moduleId, functionToken, (LPCBYTE*)&pMethodHeader, &iMethodSize), _T(" ::InstrumentMethodWith(...) => GetILFunctionBody => 0x%X")); - IMAGE_COR_ILMETHOD* pMethod = (IMAGE_COR_ILMETHOD*)pMethodHeader; - Method instumentedMethod(pMethod); + Method instumentedMethod(pMethodHeader); instumentedMethod.InsertInstructionsAtOriginalOffset(0, instructions); @@ -401,7 +409,7 @@ HRESULT CCodeCoverage::InstrumentMethodWith(ModuleID moduleId, mdToken functionT COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo->GetILFunctionBodyAllocator(moduleId, &methodMalloc), _T(" ::InstrumentMethodWith(...) => GetILFunctionBodyAllocator=> 0x%X")); - IMAGE_COR_ILMETHOD* pNewMethod = (IMAGE_COR_ILMETHOD*)methodMalloc->Alloc(instumentedMethod.GetMethodSize()); + IMAGE_COR_ILMETHOD* pNewMethod = static_cast(methodMalloc->Alloc(instumentedMethod.GetMethodSize())); instumentedMethod.WriteMethod(pNewMethod); COM_FAIL_MSG_RETURN_ERROR(m_profilerInfo->SetILFunctionBody(moduleId, functionToken, (LPCBYTE)pNewMethod), _T(" ::InstrumentMethodWith(...) => SetILFunctionBody => 0x%X")); diff --git a/main/OpenCover.Profiler/CodeCoverage.h b/main/OpenCover.Profiler/CodeCoverage.h index 8504c87cd..18dd148ee 100644 --- a/main/OpenCover.Profiler/CodeCoverage.h +++ b/main/OpenCover.Profiler/CodeCoverage.h @@ -17,6 +17,7 @@ #include #include "ReleaseTrace.h" +#include using namespace ATL; @@ -48,6 +49,11 @@ class ATL_NO_VTABLE CCodeCoverage : m_runtimeType = COR_PRF_DESKTOP_CLR; m_useOldStyle = false; m_threshold = 0U; + m_tracingEnabled = false; + m_cuckooCriticalToken = 0; + m_cuckooSafeToken = 0; + m_infoHook = nullptr; + _shortwait = 10000; } DECLARE_REGISTRY_RESOURCEID(IDR_CODECOVERAGE) @@ -71,11 +77,11 @@ END_COM_MAP() void FinalRelease() { - if (m_profilerInfo!=NULL) m_profilerInfo.Release(); - if (m_profilerInfo2!=NULL) m_profilerInfo2.Release(); - if (m_profilerInfo3!=NULL) m_profilerInfo3.Release(); + if (m_profilerInfo != nullptr) m_profilerInfo.Release(); + if (m_profilerInfo2 != nullptr) m_profilerInfo2.Release(); + if (m_profilerInfo3 != nullptr) m_profilerInfo3.Release(); #ifndef _TOOLSETV71 - if (m_profilerInfo4!=NULL) m_profilerInfo4.Release(); + if (m_profilerInfo4 != nullptr) m_profilerInfo4.Release(); #endif } @@ -95,7 +101,8 @@ END_COM_MAP() void __fastcall AddVisitPoint(ULONG uniqueId); private: - ProfilerCommunication m_host; + std::shared_ptr _host; + ULONG _shortwait; HRESULT OpenCoverInitialise(IUnknown *pICorProfilerInfoUnk); DWORD AppendProfilerEventMask(DWORD currentEventMask); @@ -188,98 +195,98 @@ END_COM_MAP() public: virtual HRESULT STDMETHODCALLTYPE Initialize( - /* [in] */ IUnknown *pICorProfilerInfoUnk); + /* [in] */ IUnknown *pICorProfilerInfoUnk) override; - virtual HRESULT STDMETHODCALLTYPE Shutdown( void); + virtual HRESULT STDMETHODCALLTYPE Shutdown( void) override; virtual HRESULT STDMETHODCALLTYPE ModuleAttachedToAssembly( /* [in] */ ModuleID moduleId, - /* [in] */ AssemblyID assemblyId); + /* [in] */ AssemblyID assemblyId) override; virtual HRESULT STDMETHODCALLTYPE ModuleLoadFinished( /* [in] */ ModuleID moduleId, - /* [in] */ HRESULT hrStatus); + /* [in] */ HRESULT hrStatus) override; virtual HRESULT STDMETHODCALLTYPE JITCompilationStarted( /* [in] */ FunctionID functionId, - /* [in] */ BOOL fIsSafeToBlock); + /* [in] */ BOOL fIsSafeToBlock) override; public: // COR_PRF_MONITOR_APPDOMAIN_LOADS virtual HRESULT STDMETHODCALLTYPE AppDomainCreationStarted( - /* [in] */ AppDomainID appDomainId) + /* [in] */ AppDomainID appDomainId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AppDomainCreationStarted(appDomainId); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainCreationFinished( /* [in] */ AppDomainID appDomainId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AppDomainCreationFinished(appDomainId, hrStatus); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownStarted( - /* [in] */ AppDomainID appDomainId) + /* [in] */ AppDomainID appDomainId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AppDomainShutdownStarted(appDomainId); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownFinished( /* [in] */ AppDomainID appDomainId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AppDomainShutdownFinished(appDomainId, hrStatus); return S_OK; } // COR_PRF_MONITOR_ASSEMBLY_LOADS virtual HRESULT STDMETHODCALLTYPE AssemblyLoadStarted( - /* [in] */ AssemblyID assemblyId) + /* [in] */ AssemblyID assemblyId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AssemblyLoadStarted(assemblyId); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyLoadFinished( /* [in] */ AssemblyID assemblyId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AssemblyLoadFinished(assemblyId, hrStatus); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadStarted( - /* [in] */ AssemblyID assemblyId) + /* [in] */ AssemblyID assemblyId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AssemblyUnloadStarted(assemblyId); return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadFinished( /* [in] */ AssemblyID assemblyId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->AssemblyUnloadFinished(assemblyId, hrStatus); return S_OK; } // COR_PRF_MONITOR_MODULE_LOADS virtual HRESULT STDMETHODCALLTYPE ModuleLoadStarted( - /* [in] */ ModuleID moduleId) + /* [in] */ ModuleID moduleId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->ModuleLoadStarted(moduleId); return S_OK; } @@ -294,18 +301,18 @@ END_COM_MAP() //} virtual HRESULT STDMETHODCALLTYPE ModuleUnloadStarted( - /* [in] */ ModuleID moduleId) + /* [in] */ ModuleID moduleId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->ModuleUnloadStarted(moduleId); return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleUnloadFinished( /* [in] */ ModuleID moduleId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->ModuleUnloadFinished(moduleId, hrStatus); return S_OK; } @@ -328,17 +335,17 @@ END_COM_MAP() virtual HRESULT STDMETHODCALLTYPE JITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, - /* [in] */ BOOL fIsSafeToBlock) + /* [in] */ BOOL fIsSafeToBlock) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->JITCompilationFinished(functionId, hrStatus, fIsSafeToBlock); return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITFunctionPitched( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->JITFunctionPitched(functionId); return S_OK; } @@ -346,29 +353,29 @@ END_COM_MAP() virtual HRESULT STDMETHODCALLTYPE JITInlining( /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, - /* [out] */ BOOL *pfShouldInline) + /* [out] */ BOOL *pfShouldInline) override { - if (m_chainedProfiler != NULL) + if (m_chainedProfiler != nullptr) return m_chainedProfiler->JITInlining(callerId, calleeId, pfShouldInline); return S_OK; } // COR_PRF_MONITOR_THREADS virtual HRESULT STDMETHODCALLTYPE ThreadCreated( - /* [in] */ ThreadID threadId); + /* [in] */ ThreadID threadId) override; virtual HRESULT STDMETHODCALLTYPE ThreadDestroyed( - /* [in] */ ThreadID threadId); + /* [in] */ ThreadID threadId) override; virtual HRESULT STDMETHODCALLTYPE ThreadAssignedToOSThread( /* [in] */ ThreadID managedThreadId, - /* [in] */ DWORD osThreadId); + /* [in] */ DWORD osThreadId) override; virtual HRESULT STDMETHODCALLTYPE ThreadNameChanged( /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, /* [in] */ - __in_ecount_opt(cchName) WCHAR name[]); + __in_ecount_opt(cchName) WCHAR name[]) override; }; OBJECT_ENTRY_AUTO(__uuidof(CodeCoverage), CCodeCoverage) diff --git a/main/OpenCover.Profiler/CodeCoverage_Callback.cpp b/main/OpenCover.Profiler/CodeCoverage_Callback.cpp index bfbdd4be5..d92b0b59f 100644 --- a/main/OpenCover.Profiler/CodeCoverage_Callback.cpp +++ b/main/OpenCover.Profiler/CodeCoverage_Callback.cpp @@ -24,7 +24,7 @@ UINT_PTR CCodeCoverage::FunctionMapper2(FunctionID functionId, void* clientData, if (profiler->GetTokenAndModule(functionId, functionToken, moduleId, modulePath, &assemblyId)) { ULONG uniqueId; - if (profiler->m_host.TrackMethod(functionToken, (LPWSTR)modulePath.c_str(), + if (profiler->_host->TrackMethod(functionToken, (LPWSTR)modulePath.c_str(), (LPWSTR)profiler->m_allowModulesAssemblyMap[modulePath].c_str(), uniqueId)) { *pbHookFunction = TRUE; @@ -46,7 +46,7 @@ void CCodeCoverage::FunctionEnter2( /*[in]*/COR_PRF_FRAME_INFO func, /*[in]*/COR_PRF_FUNCTION_ARGUMENT_INFO *argumentInfo) { - m_host.AddTestEnterPoint((ULONG)clientData); + _host->AddTestEnterPoint((ULONG)clientData); } void CCodeCoverage::FunctionLeave2( @@ -55,7 +55,7 @@ void CCodeCoverage::FunctionLeave2( /*[in]*/COR_PRF_FRAME_INFO func, /*[in]*/COR_PRF_FUNCTION_ARGUMENT_RANGE *retvalRange) { - m_host.AddTestLeavePoint((ULONG)clientData); + _host->AddTestLeavePoint((ULONG)clientData); } void CCodeCoverage::FunctionTailcall2( @@ -63,5 +63,5 @@ void CCodeCoverage::FunctionTailcall2( /*[in]*/UINT_PTR clientData, /*[in]*/COR_PRF_FRAME_INFO func) { - m_host.AddTestTailcallPoint((ULONG)clientData); + _host->AddTestTailcallPoint((ULONG)clientData); } diff --git a/main/OpenCover.Profiler/CodeCoverage_Cuckoo.cpp b/main/OpenCover.Profiler/CodeCoverage_Cuckoo.cpp index ab47a0e52..b5a53a7a3 100644 --- a/main/OpenCover.Profiler/CodeCoverage_Cuckoo.cpp +++ b/main/OpenCover.Profiler/CodeCoverage_Cuckoo.cpp @@ -37,7 +37,7 @@ HRESULT CCodeCoverage::RegisterCuckoos(ModuleID moduleId){ mdTypeDef systemObject = mdTokenNil; if (S_OK == metaDataImport->FindTypeDefByName(L"System.Object", mdTokenNil, &systemObject)) { - RELTRACE(_T("::ModuleLoadFinished(...) => Adding methods to mscorlib...")); + RELTRACE(_T("::ModuleLoadFinished(...) => Adding methods to mscorlib...\n")); mdMethodDef systemObjectCtor; COM_FAIL_MSG_RETURN_ERROR(metaDataImport->FindMethod(systemObject, L".ctor", ctorCallSignature, sizeof(ctorCallSignature), &systemObjectCtor), @@ -122,7 +122,7 @@ HRESULT CCodeCoverage::RegisterCuckoos(ModuleID moduleId){ COM_FAIL_MSG_RETURN_ERROR(metaDataEmit->DefineCustomAttribute(m_cuckooSafeToken, attributeCtor, NULL, 0, &customAttr), _T(" ::ModuleLoadFinished(...) => DefineCustomAttribute => 0x%X")); - RELTRACE(_T("::ModuleLoadFinished(...) => Added methods to mscorlib")); + RELTRACE(_T("::ModuleLoadFinished(...) => Added methods to mscorlib\n")); } return S_OK; @@ -130,7 +130,7 @@ HRESULT CCodeCoverage::RegisterCuckoos(ModuleID moduleId){ mdMemberRef CCodeCoverage::RegisterSafeCuckooMethod(ModuleID moduleId) { - ATLTRACE(_T("::RegisterSafeCuckooMethod(%X) => %s"), moduleId, CUCKOO_SAFE_METHOD_NAME); + ATLTRACE(_T("::RegisterSafeCuckooMethod(%X) => %s\n"), moduleId, CUCKOO_SAFE_METHOD_NAME); // for modules we are going to instrument add our reference to the method marked // with the SecuritySafeCriticalAttribute @@ -160,7 +160,7 @@ mdMemberRef CCodeCoverage::RegisterSafeCuckooMethod(ModuleID moduleId) /// This method makes the call into the profiler HRESULT CCodeCoverage::AddCriticalCuckooBody(ModuleID moduleId) { - ATLTRACE(_T("::AddCriticalCuckooBody => Adding VisitedCritical...")); + ATLTRACE(_T("::AddCriticalCuckooBody => Adding VisitedCritical...\n")); mdSignature pvsig = GetMethodSignatureToken_I4(moduleId); void(__fastcall *pt)(ULONG) = GetInstrumentPointVisit(); @@ -181,7 +181,7 @@ HRESULT CCodeCoverage::AddCriticalCuckooBody(ModuleID moduleId) InstrumentMethodWith(moduleId, m_cuckooCriticalToken, instructions); - ATLTRACE(_T("::AddCriticalCuckooBody => Adding VisitedCritical - Done!")); + ATLTRACE(_T("::AddCriticalCuckooBody => Adding VisitedCritical - Done!\n")); return S_OK; } @@ -190,7 +190,7 @@ HRESULT CCodeCoverage::AddCriticalCuckooBody(ModuleID moduleId) /// Calls the method that is marked with the SecurityCriticalAttribute HRESULT CCodeCoverage::AddSafeCuckooBody(ModuleID moduleId) { - ATLTRACE(_T("::AddSafeCuckooBody => Adding SafeVisited...")); + ATLTRACE(_T("::AddSafeCuckooBody => Adding SafeVisited...\n")); BYTE data[] = { (0x01 << 2) | CorILMethod_TinyFormat, CEE_RET }; Method criticalMethod((IMAGE_COR_ILMETHOD*)data); @@ -203,7 +203,7 @@ HRESULT CCodeCoverage::AddSafeCuckooBody(ModuleID moduleId) InstrumentMethodWith(moduleId, m_cuckooSafeToken, instructions); - ATLTRACE(_T("::AddSafeCuckooBody => Adding SafeVisited - Done!")); + ATLTRACE(_T("::AddSafeCuckooBody => Adding SafeVisited - Done!\n")); return S_OK; } diff --git a/main/OpenCover.Profiler/CodeCoverage_ProfilerInfo.cpp b/main/OpenCover.Profiler/CodeCoverage_ProfilerInfo.cpp index aaa996a1d..15a947862 100644 --- a/main/OpenCover.Profiler/CodeCoverage_ProfilerInfo.cpp +++ b/main/OpenCover.Profiler/CodeCoverage_ProfilerInfo.cpp @@ -172,7 +172,7 @@ std::wstring CCodeCoverage::GetTypeAndMethodName(FunctionID functionId) methodName += L"::"; methodName += szMethodName; - //ATLTRACE(_T("::GetTypeAndMethodName(%s)"), W2CT(methodName.c_str())); + //ATLTRACE(_T("::GetTypeAndMethodName(%s)\n"), W2CT(methodName.c_str())); return methodName; } diff --git a/main/OpenCover.Profiler/CodeCoverage_Support.cpp b/main/OpenCover.Profiler/CodeCoverage_Support.cpp index 10abe8cd2..4ef3b9661 100644 --- a/main/OpenCover.Profiler/CodeCoverage_Support.cpp +++ b/main/OpenCover.Profiler/CodeCoverage_Support.cpp @@ -62,7 +62,7 @@ LPSAFEARRAY GetInjectedDllAsSafeArray() EXTERN_C HRESULT STDAPICALLTYPE LoadOpenCoverSupportAssembly(IUnknown *pUnk) { - ATLTRACE(_T("****LoadInjectorAssembly - Start****")); + ATLTRACE(_T("****LoadInjectorAssembly - Start****\n")); CComPtr<_AppDomain> pAppDomain; HRESULT hr = pUnk->QueryInterface(__uuidof(_AppDomain), (void**)&pAppDomain); @@ -86,7 +86,7 @@ EXTERN_C HRESULT STDAPICALLTYPE LoadOpenCoverSupportAssembly(IUnknown *pUnk) hr = pDomainHelper->AddResolveEventHandler(); ATLASSERT(hr == S_OK); - ATLTRACE(_T("****LoadInjectorAssembly - End****")); + ATLTRACE(_T("****LoadInjectorAssembly - End****\n")); return S_OK; } @@ -98,13 +98,13 @@ HRESULT CCodeCoverage::OpenCoverSupportInitialize( ::GetEnvironmentVariable(_T("CHAIN_EXTERNAL_PROFILER"), ext, 1024); if (ext[0] != 0) { - ATLTRACE(_T("::OpenCoverSupportInitialize")); + ATLTRACE(_T("::OpenCoverSupportInitialize\n")); - ATLTRACE(_T(" ::Initialize(...) => ext = %s"), ext); + ATLTRACE(_T(" ::Initialize(...) => ext = %s\n"), ext); TCHAR loc[1024] = { 0 }; ::GetEnvironmentVariable(_T("CHAIN_EXTERNAL_PROFILER_LOCATION"), loc, 1024); - ATLTRACE(_T(" ::Initialize(...) => loc = %s"), loc); + ATLTRACE(_T(" ::Initialize(...) => loc = %s\n"), loc); CLSID clsid; HRESULT hr = CLSIDFromString(T2OLE(ext), &clsid); @@ -134,7 +134,7 @@ HRESULT CCodeCoverage::OpenCoverSupportInitialize( hr = m_chainedProfiler->Initialize(m_infoHook); - ATLTRACE(_T(" ::OpenCoverSupportInitialize => fakes = 0x%X"), hr); + ATLTRACE(_T(" ::OpenCoverSupportInitialize => fakes = 0x%X\n"), hr); } return S_OK; @@ -360,7 +360,7 @@ void CCodeCoverage::InstrumentTestToolsUITesting(FunctionID functionId, mdToken if (APPLICATIONUNDERTEST_CCTOR == typeMethodName) { - ATLTRACE(_T("::InstrumentTestToolsUITesting(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestToolsUITesting(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMethodDef invokeAttach = CreatePInvokeHook(moduleId); InstructionList instructions; @@ -374,7 +374,7 @@ void CCodeCoverage::InstrumentTestToolsUITesting(FunctionID functionId, mdToken if (APPLICATIONUNDERTEST_START == typeMethodName) { - ATLTRACE(_T("::InstrumentTestToolsUITesting(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestToolsUITesting(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMemberRef memberRef = GetUITestingHelperMethodRef(_T("PropagateRequiredEnvironmentVariables"), moduleId); InstructionList instructions; @@ -395,7 +395,7 @@ void CCodeCoverage::InstrumentTestPlatformUtilities(FunctionID functionId, mdTok if (DEFAULTTESTEXECUTOR_CTOR == typeMethodName) { - ATLTRACE(_T("::InstrumentTestPlatformUtilities(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestPlatformUtilities(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMethodDef invokeAttach = CreatePInvokeHook(moduleId); InstructionList instructions; @@ -409,7 +409,7 @@ void CCodeCoverage::InstrumentTestPlatformUtilities(FunctionID functionId, mdTok if (DEFAULTTESTEXECUTOR_LAUNCHPROCESS == typeMethodName) { - ATLTRACE(_T("::InstrumentTestPlatformUtilities(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestPlatformUtilities(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMemberRef memberRef = GetFakesHelperMethodRef(_T("LoadOpenCoverProfilerInstead"), moduleId); InstructionList instructions; @@ -430,7 +430,7 @@ void CCodeCoverage::InstrumentTestPlatformTestExecutor(FunctionID functionId, md if (TESTEXECUTORMAIN_CTOR == typeMethodName) { - ATLTRACE(_T("::InstrumentTestPlatformTestExecutor(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestPlatformTestExecutor(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMethodDef invokeAttach = CreatePInvokeHook(moduleId); @@ -445,7 +445,7 @@ void CCodeCoverage::InstrumentTestPlatformTestExecutor(FunctionID functionId, md if (TESTEXECUTORMAIN_RUN == typeMethodName) { - ATLTRACE(_T("::InstrumentTestPlatformTestExecutor(%X, ...) => %d, %X => %s"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); + ATLTRACE(_T("::InstrumentTestPlatformTestExecutor(%X, ...) => %d, %X => %s\n"), functionId, functionToken, moduleId, W2CT(typeMethodName.c_str())); mdMemberRef memberRef = GetFakesHelperMethodRef(_T("PretendWeLoadedFakesProfiler"), moduleId); InstructionList instructions; diff --git a/main/OpenCover.Profiler/CodeCoverage_Thread.cpp b/main/OpenCover.Profiler/CodeCoverage_Thread.cpp index 921af6db6..41b73732d 100644 --- a/main/OpenCover.Profiler/CodeCoverage_Thread.cpp +++ b/main/OpenCover.Profiler/CodeCoverage_Thread.cpp @@ -7,8 +7,8 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ThreadCreated( /* [in] */ ThreadID threadId) { - ATLTRACE(_T("::ThreadCreated(%d)"), threadId); - if (m_chainedProfiler != NULL) + ATLTRACE(_T("::ThreadCreated(%d)\n"), threadId); + if (m_chainedProfiler != nullptr) m_chainedProfiler->ThreadCreated(threadId); return S_OK; } @@ -16,12 +16,12 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ThreadCreated( HRESULT STDMETHODCALLTYPE CCodeCoverage::ThreadDestroyed( /* [in] */ ThreadID threadId) { - ATLTRACE(_T("::ThreadDestroyed(%d)"), threadId); - if (m_chainedProfiler != NULL) + ATLTRACE(_T("::ThreadDestroyed(%d)\n"), threadId); + if (m_chainedProfiler != nullptr) m_chainedProfiler->ThreadDestroyed(threadId); if (!m_tracingEnabled){ - m_host.ThreadDestroyed(threadId); + _host->ThreadDestroyed(threadId); } return S_OK; @@ -31,12 +31,12 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ThreadAssignedToOSThread( /* [in] */ ThreadID managedThreadId, /* [in] */ DWORD osThreadId) { - ATLTRACE(_T("::ThreadAssignedToOSThread(%d, %d)"), managedThreadId, osThreadId); - if (m_chainedProfiler != NULL) + ATLTRACE(_T("::ThreadAssignedToOSThread(%d, %d)\n"), managedThreadId, osThreadId); + if (m_chainedProfiler != nullptr) m_chainedProfiler->ThreadAssignedToOSThread(managedThreadId, osThreadId); if (!m_tracingEnabled){ - m_host.ThreadCreated(managedThreadId, osThreadId); + _host->ThreadCreated(managedThreadId, osThreadId); } return S_OK; @@ -48,8 +48,8 @@ HRESULT STDMETHODCALLTYPE CCodeCoverage::ThreadNameChanged( /* [in] */ __in_ecount_opt(cchName) WCHAR name[]) { - ATLTRACE(_T("::ThreadNameChanged(%d, %s)"), threadId, W2T(name)); - if (m_chainedProfiler != NULL) + ATLTRACE(_T("::ThreadNameChanged(%d, %s)\n"), threadId, W2T(name)); + if (m_chainedProfiler != nullptr) m_chainedProfiler->ThreadNameChanged(threadId, cchName, name); return S_OK; } diff --git a/main/OpenCover.Profiler/CoverageInstrumentation.h b/main/OpenCover.Profiler/CoverageInstrumentation.h index 1ccbcd6ad..fa223af33 100644 --- a/main/OpenCover.Profiler/CoverageInstrumentation.h +++ b/main/OpenCover.Profiler/CoverageInstrumentation.h @@ -16,7 +16,7 @@ namespace CoverageInstrumentation inline void AddSequenceCoverage(IM instrumentMethod, Method& method, std::vector points) { if (points.size() == 0) return; - for (auto it = points.begin(); it != points.end(); it++) + for (auto it = points.begin(); it != points.end(); ++it) { InstructionList instructions; instrumentMethod(instructions, (*it).UniqueId); @@ -59,7 +59,7 @@ namespace CoverageInstrumentation instructions.push_back(pJumpNext); // collect branches instrumentation - for(auto sbit = pCurrent->m_branches.begin(); sbit != pCurrent->m_branches.end(); sbit++) + for(auto sbit = pCurrent->m_branches.begin(); sbit != pCurrent->m_branches.end(); ++sbit) { idx++; uniqueId = (*std::find_if(points.begin(), points.end(), [pCurrent, idx](BranchPoint &bp){return bp.Offset == pCurrent->m_origOffset && bp.Path == idx;})).UniqueId; @@ -89,7 +89,9 @@ namespace CoverageInstrumentation Instruction* pElse = instrumentMethod(instructions, storedId); pJumpNext->m_branches[0] = pElse; // rewire pJumpNext + // ReSharper disable once CppPossiblyErroneousEmptyStatements for (it = method.m_instructions.begin(); *it != pNext; ++it); + method.m_instructions.insert(it, instructions.begin(), instructions.end()); // restore 'it' position diff --git a/main/OpenCover.Profiler/ExceptionHandler.cpp b/main/OpenCover.Profiler/ExceptionHandler.cpp index 08cac017e..bf68419da 100644 --- a/main/OpenCover.Profiler/ExceptionHandler.cpp +++ b/main/OpenCover.Profiler/ExceptionHandler.cpp @@ -9,12 +9,13 @@ ExceptionHandler::ExceptionHandler(void) { - m_tryStart = NULL; - m_tryEnd = NULL; - m_handlerStart = NULL; - m_handlerEnd = NULL; - m_filterStart = NULL; + m_tryStart = nullptr; + m_tryEnd = nullptr; + m_handlerStart = nullptr; + m_handlerEnd = nullptr; + m_filterStart = nullptr; m_token = 0; + m_handlerType = COR_ILEXCEPTION_CLAUSE_NONE; } diff --git a/main/OpenCover.Profiler/Instruction.cpp b/main/OpenCover.Profiler/Instruction.cpp index 72650958b..c0e3fb6c9 100644 --- a/main/OpenCover.Profiler/Instruction.cpp +++ b/main/OpenCover.Profiler/Instruction.cpp @@ -13,6 +13,7 @@ Instruction::Instruction(void) m_offset = -1; m_isBranch = false; m_origOffset = -1; + m_jump = nullptr; } Instruction::Instruction(CanonicalName operation, ULONGLONG operand) @@ -22,6 +23,7 @@ Instruction::Instruction(CanonicalName operation, ULONGLONG operand) m_offset = -1; m_isBranch = false; m_origOffset = -1; + m_jump = nullptr; } Instruction::Instruction(CanonicalName operation) @@ -31,6 +33,7 @@ Instruction::Instruction(CanonicalName operation) m_offset = -1; m_isBranch = false; m_origOffset = -1; + m_jump = nullptr; } Instruction::~Instruction(void) diff --git a/main/OpenCover.Profiler/Method.cpp b/main/OpenCover.Profiler/Method.cpp index da2c6a48c..809acf519 100644 --- a/main/OpenCover.Profiler/Method.cpp +++ b/main/OpenCover.Profiler/Method.cpp @@ -38,20 +38,20 @@ Method::~Method() void Method::ReadMethod(IMAGE_COR_ILMETHOD* pMethod) { BYTE* pCode; - COR_ILMETHOD_FAT* fatImage = (COR_ILMETHOD_FAT*)&pMethod->Fat; + auto fatImage = static_cast(&pMethod->Fat); if(!fatImage->IsFat()) { - ATLTRACE(_T("TINY")); - COR_ILMETHOD_TINY* tinyImage = (COR_ILMETHOD_TINY*)&pMethod->Tiny; + ATLTRACE(_T("TINY\n")); + auto tinyImage = static_cast(&pMethod->Tiny); m_header.CodeSize = tinyImage->GetCodeSize(); pCode = tinyImage->GetCode(); - ATLTRACE(_T("TINY(%X) => (%d + 1) : %d"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack); + ATLTRACE(_T("TINY(%X) => (%d + 1) : %d\n"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack); } else { memcpy(&m_header, pMethod, fatImage->Size * sizeof(DWORD)); pCode = fatImage->GetCode(); - ATLTRACE(_T("FAT(%X) => (%d + 12) : %d"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack); + ATLTRACE(_T("FAT(%X) => (%d + 12) : %d\n"), m_header.CodeSize, m_header.CodeSize, m_header.MaxStack); } SetBuffer(pCode); ReadBody(); @@ -64,7 +64,7 @@ void Method::ReadMethod(IMAGE_COR_ILMETHOD* pMethod) void Method::WriteMethod(IMAGE_COR_ILMETHOD* pMethod) { BYTE* pCode; - COR_ILMETHOD_FAT* fatImage = (COR_ILMETHOD_FAT*)&pMethod->Fat; + auto fatImage = static_cast(&pMethod->Fat); m_header.Flags &= ~CorILMethod_MoreSects; if (m_exceptions.size() > 0) @@ -80,7 +80,7 @@ void Method::WriteMethod(IMAGE_COR_ILMETHOD* pMethod) for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it) { - OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; + auto& details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; if (details.op1 == REFPRE) { Write(details.op2); @@ -100,13 +100,13 @@ void Method::WriteMethod(IMAGE_COR_ILMETHOD* pMethod) case Null: break; case Byte: - Write((BYTE)(*it)->m_operand); + Write(static_cast((*it)->m_operand)); break; case Word: - Write((USHORT)(*it)->m_operand); + Write(static_cast((*it)->m_operand)); break; case Dword: - Write((ULONG)(*it)->m_operand); + Write(static_cast((*it)->m_operand)); break; case Qword: Write((*it)->m_operand); @@ -117,7 +117,7 @@ void Method::WriteMethod(IMAGE_COR_ILMETHOD* pMethod) if ((*it)->m_operation == CEE_SWITCH) { - for (std::vector::iterator offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; offsetIter++) + for (auto offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end(); ++offsetIter) { Write(*offsetIter); } @@ -210,17 +210,17 @@ void Method::ReadBody() { if (details.operandSize==1) { - pInstruction->m_branchOffsets.push_back((char)(BYTE)pInstruction->m_operand); + pInstruction->m_branchOffsets.push_back(static_cast(static_cast(pInstruction->m_operand))); } else { - pInstruction->m_branchOffsets.push_back((ULONG)pInstruction->m_operand); + pInstruction->m_branchOffsets.push_back(static_cast(pInstruction->m_operand)); } } if (pInstruction->m_operation == CEE_SWITCH) { - DWORD numbranches = (DWORD)pInstruction->m_operand; + auto numbranches = static_cast(pInstruction->m_operand); while(numbranches-- != 0) pInstruction->m_branchOffsets.push_back(Read()); } @@ -229,7 +229,7 @@ void Method::ReadBody() ReadSections(); - SetBuffer(NULL); + SetBuffer(nullptr); //DumpIL(); @@ -248,7 +248,7 @@ void Method::ReadSections() { if ((m_header.Flags & CorILMethod_MoreSects) == CorILMethod_MoreSects) { - BYTE flags = 0; + BYTE flags; do { Align(); // must be DWORD aligned @@ -258,13 +258,13 @@ void Method::ReadSections() { Advance(-1); int count = ((Read() >> 8) / 24); - for (int i = 0; i < count; i++) + for (auto i = 0; i < count; i++) { - CorExceptionFlag type = (CorExceptionFlag)Read(); - long tryStart = Read(); - long tryEnd = Read(); - long handlerStart = Read(); - long handlerEnd = Read(); + auto type = static_cast(Read()); + auto tryStart = Read(); + auto tryEnd = Read(); + auto handlerStart = Read(); + auto handlerEnd = Read(); long filterStart = 0; ULONG token = 0; switch (type) @@ -276,7 +276,7 @@ void Method::ReadSections() token = Read(); break; } - ExceptionHandler * pSection = new ExceptionHandler(); + auto pSection = new ExceptionHandler(); pSection->m_handlerType = type; pSection->m_tryStart = GetInstructionAtOffset(tryStart); pSection->m_tryEnd = GetInstructionAtOffset(tryStart + tryEnd); @@ -296,11 +296,11 @@ void Method::ReadSections() } else { - int count = (int)(Read() / 12); + auto count = static_cast(Read() / 12); Advance(2); - for (int i = 0; i < count; i++) + for (auto i = 0; i < count; i++) { - CorExceptionFlag type = (CorExceptionFlag)Read(); + auto type = static_cast(Read()); long tryStart = Read(); long tryEnd = Read(); long handlerStart = Read(); @@ -353,7 +353,7 @@ Instruction * Method::GetInstructionAtOffset(long offset) } } _ASSERTE(FALSE); - return NULL; + return nullptr; } /// Gets the Instruction that has (is at) the specified offset. @@ -387,19 +387,19 @@ Instruction * Method::GetInstructionAtOffset(long offset, bool isFinally, bool i if (isFinally || isFault || isFilter || isTyped) { - Instruction *pLast = m_instructions.back(); - OperationDetails &details = Operations::m_mapNameOperationDetails[pLast->m_operation]; + auto pLast = m_instructions.back(); + auto& details = Operations::m_mapNameOperationDetails[pLast->m_operation]; if (offset == pLast->m_offset + details.length + details.operandSize) { // add a code label to hang the clause handler end off - Instruction *pInstruction = new Instruction(CEE_CODE_LABEL); + auto pInstruction = new Instruction(CEE_CODE_LABEL); pInstruction->m_offset = offset; m_instructions.push_back(pInstruction); return pInstruction; } } _ASSERTE(FALSE); - return NULL; + return nullptr; } /// Uses the current offsets and locates the instructions that reside that offset to @@ -412,18 +412,18 @@ void Method::ResolveBranches() for (auto it = m_instructions.begin(); it != m_instructions.end() ; ++it) { (*it)->m_branches.clear(); - OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; - long baseOffset = (*it)->m_offset + details.length + details.operandSize; + auto& details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; + auto baseOffset = (*it)->m_offset + details.length + details.operandSize; if ((*it)->m_operation == CEE_SWITCH) { - baseOffset += (4*(long)(*it)->m_operand); + baseOffset += (4*static_cast((*it)->m_operand)); } - for (std::vector::iterator offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; offsetIter++) + for (auto offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; ++offsetIter) { - long offset = baseOffset + (*offsetIter); - Instruction * instruction = GetInstructionAtOffset(offset); - if (instruction != NULL) + auto offset = baseOffset + (*offsetIter); + auto instruction = GetInstructionAtOffset(offset); + if (instruction != nullptr) { (*it)->m_branches.push_back(instruction); } @@ -437,25 +437,25 @@ void Method::ResolveBranches() void Method::DumpIL() { #ifdef DUMP_IL - ATLTRACE(_T("-+-+-+-+-+-+-+-+-+-+-+-+- START -+-+-+-+-+-+-+-+-+-+-+-+")); + ATLTRACE(_T("-+-+-+-+-+-+-+-+-+-+-+-+- START -+-+-+-+-+-+-+-+-+-+-+-+\n")); for (auto it = m_instructions.begin(); it != m_instructions.end() ; ++it) { - OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; + auto& details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; if (details.operandSize == Null) { - ATLTRACE(_T("IL_%04X %s"), (*it)->m_offset, details.stringName); + ATLTRACE(_T("IL_%04X %s\n"), (*it)->m_offset, details.stringName); } else { if (details.operandParam == ShortInlineBrTarget || details.operandParam == InlineBrTarget) { - long offset = (*it)->m_offset + (*it)->m_branchOffsets[0] + details.length + details.operandSize; - ATLTRACE(_T("IL_%04X %s IL_%04X"), + auto offset = (*it)->m_offset + (*it)->m_branchOffsets[0] + details.length + details.operandSize; + ATLTRACE(_T("IL_%04X %s IL_%04X\n"), (*it)->m_offset, details.stringName, offset); } else if (details.operandParam == InlineMethod || details.operandParam == InlineString) { - ATLTRACE(_T("IL_%04X %s (%02X)%02X%02X%02X"), + ATLTRACE(_T("IL_%04X %s (%02X)%02X%02X%02X\n"), (*it)->m_offset, details.stringName, (BYTE)((*it)->m_operand >> 24), (BYTE)((*it)->m_operand >> 16), @@ -464,30 +464,30 @@ void Method::DumpIL() } else if (details.operandSize == Byte) { - ATLTRACE(_T("IL_%04X %s %02X"), + ATLTRACE(_T("IL_%04X %s %02X\n"), (*it)->m_offset, details.stringName, (*it)->m_operand); } else if (details.operandSize == Word) { - ATLTRACE(_T("IL_%04X %s %04X"), + ATLTRACE(_T("IL_%04X %s %04X\n"), (*it)->m_offset, details.stringName, (*it)->m_operand); } else if (details.operandSize == Dword) { - ATLTRACE(_T("IL_%04X %s %08X"), + ATLTRACE(_T("IL_%04X %s %08X\n"), (*it)->m_offset, details.stringName, (*it)->m_operand); } else { - ATLTRACE(_T("IL_%04X %s %X"), (*it)->m_offset, details.stringName, (*it)->m_operand); + ATLTRACE(_T("IL_%04X %s %X\n"), (*it)->m_offset, details.stringName, (*it)->m_operand); } } - for (std::vector::iterator offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; offsetIter++) + for (auto offsetIter = (*it)->m_branchOffsets.begin(); offsetIter != (*it)->m_branchOffsets.end() ; ++offsetIter) { if ((*it)->m_operation == CEE_SWITCH) { - long offset = (*it)->m_offset + (4*(long)(*it)->m_operand) + (*offsetIter) + details.length + details.operandSize; - ATLTRACE(_T(" IL_%04X"), offset); + auto offset = (*it)->m_offset + (4*static_cast((*it)->m_operand)) + (*offsetIter) + details.length + details.operandSize; + ATLTRACE(_T(" IL_%04X\n"), offset); } } } @@ -495,16 +495,16 @@ void Method::DumpIL() int i = 0; for (auto it = m_exceptions.begin(); it != m_exceptions.end() ; ++it) { - ATLTRACE(_T("Section %d: %d %04X %04X %04X %04X %04X %08X"), + ATLTRACE(_T("Section %d: %d %04X %04X %04X %04X %04X %08X\n"), i++, (*it)->m_handlerType, - (*it)->m_tryStart != NULL ? (*it)->m_tryStart->m_offset : 0, - (*it)->m_tryEnd != NULL ? (*it)->m_tryEnd->m_offset : 0, - (*it)->m_handlerStart != NULL ? (*it)->m_handlerStart->m_offset : 0, - (*it)->m_handlerEnd != NULL ? (*it)->m_handlerEnd->m_offset : 0, - (*it)->m_filterStart != NULL ? (*it)->m_filterStart->m_offset : 0, + (*it)->m_tryStart != nullptr ? (*it)->m_tryStart->m_offset : 0, + (*it)->m_tryEnd != nullptr ? (*it)->m_tryEnd->m_offset : 0, + (*it)->m_handlerStart != nullptr ? (*it)->m_handlerStart->m_offset : 0, + (*it)->m_handlerEnd != nullptr ? (*it)->m_handlerEnd->m_offset : 0, + (*it)->m_filterStart != nullptr ? (*it)->m_filterStart->m_offset : 0, (*it)->m_token); } - ATLTRACE(_T("-+-+-+-+-+-+-+-+-+-+-+-+- END -+-+-+-+-+-+-+-+-+-+-+-+")); + ATLTRACE(_T("-+-+-+-+-+-+-+-+-+-+-+-+- END -+-+-+-+-+-+-+-+-+-+-+-+\n")); #endif } @@ -583,25 +583,25 @@ void Method::RecalculateOffsets() int position = 0; for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it) { - OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; + auto& details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; (*it)->m_offset = position; position += details.length; position += details.operandSize; if((*it)->m_operation == CEE_SWITCH) { - position += 4*(long)(*it)->m_operand; + position += 4*static_cast((*it)->m_operand); } } for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it) { - OperationDetails &details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; + auto& details = Operations::m_mapNameOperationDetails[(*it)->m_operation]; if ((*it)->m_isBranch) { (*it)->m_branchOffsets.clear(); if((*it)->m_operation == CEE_SWITCH) { - long offset = ((*it)->m_offset + details.length + details.operandSize + (4*(long)(*it)->m_operand)); + auto offset = ((*it)->m_offset + details.length + details.operandSize + (4*static_cast((*it)->m_operand))); for (auto bit = (*it)->m_branches.begin(); bit != (*it)->m_branches.end(); ++bit) { (*it)->m_branchOffsets.push_back((*bit)->m_offset - offset); @@ -610,7 +610,7 @@ void Method::RecalculateOffsets() else { (*it)->m_operand = (*it)->m_branches[0]->m_offset - ((*it)->m_offset + details.length + details.operandSize); - (*it)->m_branchOffsets.push_back((long)(*it)->m_operand); + (*it)->m_branchOffsets.push_back(static_cast((*it)->m_operand)); } } } @@ -624,8 +624,8 @@ void Method::RecalculateOffsets() /// beforehand if any instrumentation has been done long Method::GetMethodSize() { - Instruction * lastInstruction = m_instructions.back(); - OperationDetails &details = Operations::m_mapNameOperationDetails[lastInstruction->m_operation]; + auto lastInstruction = m_instructions.back(); + auto& details = Operations::m_mapNameOperationDetails[lastInstruction->m_operation]; m_header.CodeSize = lastInstruction->m_offset + details.length + details.operandSize; long size = sizeof(IMAGE_COR_ILMETHOD_FAT) + m_header.CodeSize; @@ -636,7 +636,7 @@ long Method::GetMethodSize() m_header.Flags |= CorILMethod_MoreSects; long align = sizeof(DWORD) - 1; size = ((size + align) & ~align); - size += (((long)m_exceptions.size() * 6) + 1) * sizeof(long); + size += ((static_cast(m_exceptions.size()) * 6) + 1) * sizeof(long); } return size; @@ -679,12 +679,12 @@ void Method::InsertInstructionsAtOffset(long offset, const InstructionList &inst clone.push_back(new Instruction(*(*it))); } - long actualOffset = 0; + //long actualOffset; for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it) { if ((*it)->m_offset == offset) { - actualOffset = (*it)->m_offset; + //actualOffset = (*it)->m_offset; m_instructions.insert(++it, clone.begin(), clone.end()); break; } @@ -693,8 +693,8 @@ void Method::InsertInstructionsAtOffset(long offset, const InstructionList &inst for (auto it = m_instructions.begin(); it != m_instructions.end(); ++it) { if ((*it)->m_origOffset == offset) - { - Instruction orig = *(*it); + { + auto orig = *(*it); for (unsigned int i=0;im_jump = NULL; - Instruction* jump = NULL; - Instruction* jumpTo = NULL; - if (next != NULL) + next->m_jump = nullptr; + Instruction* jump; + Instruction* jumpTo; + if (next != nullptr) { while ( next->m_operation == CEE_BR || next->m_operation == CEE_BR_S ) { _ASSERTE(next->m_isBranch); @@ -828,12 +828,12 @@ Instruction* Method::EndOfBranch(Instruction* toFollow) _ASSERTE(next->m_branches[0] != NULL); jumpTo = next->m_branches[0]; _ASSERTE(jumpTo != NULL); - if ( jumpTo == NULL ) break; + if ( jumpTo == nullptr ) break; jump = next; // store last BR instruction next = jumpTo; // store last BR jump-target instruction found (so far) next->m_jump = jump; // set m_jump to last BR instruction } } - return next == NULL? toFollow : next; + return next == nullptr ? toFollow : next; } diff --git a/main/OpenCover.Profiler/ProfileBase.h b/main/OpenCover.Profiler/ProfileBase.h index d5a7c1472..502515e70 100644 --- a/main/OpenCover.Profiler/ProfileBase.h +++ b/main/OpenCover.Profiler/ProfileBase.h @@ -14,303 +14,307 @@ class CProfilerBase : public ICorProfilerCallback3 #endif // ICorProfilerCallback public: + virtual ~CProfilerBase() + { + } + virtual HRESULT STDMETHODCALLTYPE Initialize( - /* [in] */ IUnknown *pICorProfilerInfoUnk) + /* [in] */ IUnknown *pICorProfilerInfoUnk) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE Shutdown( void) + virtual HRESULT STDMETHODCALLTYPE Shutdown( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainCreationStarted( - /* [in] */ AppDomainID appDomainId) + /* [in] */ AppDomainID appDomainId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainCreationFinished( /* [in] */ AppDomainID appDomainId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownStarted( - /* [in] */ AppDomainID appDomainId) + /* [in] */ AppDomainID appDomainId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AppDomainShutdownFinished( /* [in] */ AppDomainID appDomainId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyLoadStarted( - /* [in] */ AssemblyID assemblyId) + /* [in] */ AssemblyID assemblyId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyLoadFinished( /* [in] */ AssemblyID assemblyId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadStarted( - /* [in] */ AssemblyID assemblyId) + /* [in] */ AssemblyID assemblyId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadFinished( /* [in] */ AssemblyID assemblyId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleLoadStarted( - /* [in] */ ModuleID moduleId) + /* [in] */ ModuleID moduleId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleLoadFinished( /* [in] */ ModuleID moduleId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleUnloadStarted( - /* [in] */ ModuleID moduleId) + /* [in] */ ModuleID moduleId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleUnloadFinished( /* [in] */ ModuleID moduleId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ModuleAttachedToAssembly( /* [in] */ ModuleID moduleId, - /* [in] */ AssemblyID assemblyId) + /* [in] */ AssemblyID assemblyId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ClassLoadStarted( - /* [in] */ ClassID classId) + /* [in] */ ClassID classId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ClassLoadFinished( /* [in] */ ClassID classId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ClassUnloadStarted( - /* [in] */ ClassID classId) + /* [in] */ ClassID classId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ClassUnloadFinished( /* [in] */ ClassID classId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE FunctionUnloadStarted( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITCompilationStarted( /* [in] */ FunctionID functionId, - /* [in] */ BOOL fIsSafeToBlock) + /* [in] */ BOOL fIsSafeToBlock) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ HRESULT hrStatus, - /* [in] */ BOOL fIsSafeToBlock) + /* [in] */ BOOL fIsSafeToBlock) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchStarted( /* [in] */ FunctionID functionId, - /* [out] */ BOOL *pbUseCachedFunction) + /* [out] */ BOOL *pbUseCachedFunction) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITCachedFunctionSearchFinished( /* [in] */ FunctionID functionId, - /* [in] */ COR_PRF_JIT_CACHE result) + /* [in] */ COR_PRF_JIT_CACHE result) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITFunctionPitched( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE JITInlining( /* [in] */ FunctionID callerId, /* [in] */ FunctionID calleeId, - /* [out] */ BOOL *pfShouldInline) + /* [out] */ BOOL *pfShouldInline) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ThreadCreated( - /* [in] */ ThreadID threadId) + /* [in] */ ThreadID threadId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ThreadDestroyed( - /* [in] */ ThreadID threadId) + /* [in] */ ThreadID threadId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ThreadAssignedToOSThread( /* [in] */ ThreadID managedThreadId, - /* [in] */ DWORD osThreadId) + /* [in] */ DWORD osThreadId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationStarted( void) + virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationStarted( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RemotingClientSendingMessage( /* [in] */ GUID *pCookie, - /* [in] */ BOOL fIsAsync) + /* [in] */ BOOL fIsAsync) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RemotingClientReceivingReply( /* [in] */ GUID *pCookie, - /* [in] */ BOOL fIsAsync) + /* [in] */ BOOL fIsAsync) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationFinished( void) + virtual HRESULT STDMETHODCALLTYPE RemotingClientInvocationFinished( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RemotingServerReceivingMessage( /* [in] */ GUID *pCookie, - /* [in] */ BOOL fIsAsync) + /* [in] */ BOOL fIsAsync) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationStarted( void) + virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationStarted( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationReturned( void) + virtual HRESULT STDMETHODCALLTYPE RemotingServerInvocationReturned( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RemotingServerSendingReply( /* [in] */ GUID *pCookie, - /* [in] */ BOOL fIsAsync) + /* [in] */ BOOL fIsAsync) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE UnmanagedToManagedTransition( /* [in] */ FunctionID functionId, - /* [in] */ COR_PRF_TRANSITION_REASON reason ) + /* [in] */ COR_PRF_TRANSITION_REASON reason ) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ManagedToUnmanagedTransition( /* [in] */ FunctionID functionId, - /* [in] */ COR_PRF_TRANSITION_REASON reason) + /* [in] */ COR_PRF_TRANSITION_REASON reason) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendStarted( - /* [in] */ COR_PRF_SUSPEND_REASON suspendReason) + /* [in] */ COR_PRF_SUSPEND_REASON suspendReason) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendFinished( void) + virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendFinished( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendAborted( void) + virtual HRESULT STDMETHODCALLTYPE RuntimeSuspendAborted( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RuntimeResumeStarted( void) + virtual HRESULT STDMETHODCALLTYPE RuntimeResumeStarted( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE RuntimeResumeFinished( void) + virtual HRESULT STDMETHODCALLTYPE RuntimeResumeFinished( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RuntimeThreadSuspended( - /* [in] */ ThreadID threadId) + /* [in] */ ThreadID threadId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RuntimeThreadResumed( - /* [in] */ ThreadID threadId) + /* [in] */ ThreadID threadId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE MovedReferences( /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], - /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) + /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ObjectAllocated( /* [in] */ ObjectID objectId, - /* [in] */ ClassID classId) + /* [in] */ ClassID classId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ObjectsAllocatedByClass( /* [in] */ ULONG cClassCount, /* [size_is][in] */ ClassID classIds[ ], - /* [size_is][in] */ ULONG cObjects[ ]) + /* [size_is][in] */ ULONG cObjects[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ObjectReferences( /* [in] */ ObjectID objectId, /* [in] */ ClassID classId, /* [in] */ ULONG cObjectRefs, - /* [size_is][in] */ ObjectID objectRefIds[ ]) + /* [size_is][in] */ ObjectID objectRefIds[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RootReferences( /* [in] */ ULONG cRootRefs, - /* [size_is][in] */ ObjectID rootRefIds[ ]) + /* [size_is][in] */ ObjectID rootRefIds[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionThrown( - /* [in] */ ObjectID thrownObjectId) + /* [in] */ ObjectID thrownObjectId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionEnter( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionLeave( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFunctionLeave( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterEnter( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterLeave( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionSearchFilterLeave( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionSearchCatcherFound( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerEnter( - /* [in] */ UINT_PTR __unused) + /* [in] */ UINT_PTR __unused) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionOSHandlerLeave( - /* [in] */ UINT_PTR __unused) + /* [in] */ UINT_PTR __unused) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionEnter( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionLeave( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFunctionLeave( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyEnter( - /* [in] */ FunctionID functionId) + /* [in] */ FunctionID functionId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyLeave( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwindFinallyLeave( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherEnter( /* [in] */ FunctionID functionId, - /* [in] */ ObjectID objectId) + /* [in] */ ObjectID objectId) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherLeave( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionCatcherLeave( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE COMClassicVTableCreated( /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, /* [in] */ void *pVTable, - /* [in] */ ULONG cSlots) + /* [in] */ ULONG cSlots) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE COMClassicVTableDestroyed( /* [in] */ ClassID wrappedClassId, /* [in] */ REFGUID implementedIID, - /* [in] */ void *pVTable) + /* [in] */ void *pVTable) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherFound( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherFound( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherExecute( void) + virtual HRESULT STDMETHODCALLTYPE ExceptionCLRCatcherExecute( void) override { return S_OK; } // ICorProfilerCallback2 @@ -319,27 +323,27 @@ class CProfilerBase : public ICorProfilerCallback3 /* [in] */ ThreadID threadId, /* [in] */ ULONG cchName, /* [in] */ - __in_ecount_opt(cchName) WCHAR name[ ]) + __in_ecount_opt(cchName) WCHAR name[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE GarbageCollectionStarted( /* [in] */ int cGenerations, /* [size_is][in] */ BOOL generationCollected[ ], - /* [in] */ COR_PRF_GC_REASON reason) + /* [in] */ COR_PRF_GC_REASON reason) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE SurvivingReferences( /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], - /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) + /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GarbageCollectionFinished( void) + virtual HRESULT STDMETHODCALLTYPE GarbageCollectionFinished( void) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE FinalizeableObjectQueued( /* [in] */ DWORD finalizerFlags, - /* [in] */ ObjectID objectID) + /* [in] */ ObjectID objectID) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE RootReferences2( @@ -347,16 +351,16 @@ class CProfilerBase : public ICorProfilerCallback3 /* [size_is][in] */ ObjectID rootRefIds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ], /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ], - /* [size_is][in] */ UINT_PTR rootIds[ ]) + /* [size_is][in] */ UINT_PTR rootIds[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE HandleCreated( /* [in] */ GCHandleID handleId, - /* [in] */ ObjectID initialObjectId) + /* [in] */ ObjectID initialObjectId) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE HandleDestroyed( - /* [in] */ GCHandleID handleId) + /* [in] */ GCHandleID handleId) override { return S_OK; } // ICorProfilerCallback3 @@ -364,13 +368,13 @@ class CProfilerBase : public ICorProfilerCallback3 virtual HRESULT STDMETHODCALLTYPE InitializeForAttach( /* [in] */ IUnknown *pCorProfilerInfoUnk, /* [in] */ void *pvClientData, - /* [in] */ UINT cbClientData) + /* [in] */ UINT cbClientData) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ProfilerAttachComplete( void) + virtual HRESULT STDMETHODCALLTYPE ProfilerAttachComplete( void) override { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ProfilerDetachSucceeded( void) + virtual HRESULT STDMETHODCALLTYPE ProfilerDetachSucceeded( void) override { return S_OK; } #ifndef _TOOLSETV71 @@ -379,41 +383,41 @@ class CProfilerBase : public ICorProfilerCallback3 virtual HRESULT STDMETHODCALLTYPE ReJITCompilationStarted( /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, - /* [in] */ BOOL fIsSafeToBlock) - { return S_OK; } + /* [in] */ BOOL fIsSafeToBlock) override + { return S_OK; } virtual HRESULT STDMETHODCALLTYPE GetReJITParameters( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, - /* [in] */ ICorProfilerFunctionControl *pFunctionControl) - { return S_OK; } + /* [in] */ ICorProfilerFunctionControl *pFunctionControl) override + { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ReJITCompilationFinished( /* [in] */ FunctionID functionId, /* [in] */ ReJITID rejitId, /* [in] */ HRESULT hrStatus, - /* [in] */ BOOL fIsSafeToBlock) + /* [in] */ BOOL fIsSafeToBlock) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ReJITError( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [in] */ FunctionID functionId, - /* [in] */ HRESULT hrStatus) + /* [in] */ HRESULT hrStatus) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE MovedReferences2( /* [in] */ ULONG cMovedObjectIDRanges, /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ], /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ], - /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) + /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) override { return S_OK; } virtual HRESULT STDMETHODCALLTYPE SurvivingReferences2( /* [in] */ ULONG cSurvivingObjectIDRanges, /* [size_is][in] */ ObjectID objectIDRangeStart[ ], - /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) - { return S_OK; } + /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]) override + { return S_OK; } // ICorProfilerCallback5 public: @@ -421,7 +425,7 @@ class CProfilerBase : public ICorProfilerCallback3 /* [in] */ ULONG cRootRefs, /* [size_is][in] */ ObjectID keyRefIds[ ], /* [size_is][in] */ ObjectID valueRefIds[ ], - /* [size_is][in] */ GCHandleID rootIds[ ]) + /* [size_is][in] */ GCHandleID rootIds[ ]) override { return S_OK; } #endif diff --git a/main/OpenCover.Profiler/ProfilerCommunication.cpp b/main/OpenCover.Profiler/ProfilerCommunication.cpp index 0e7501ce7..03ca3def2 100644 --- a/main/OpenCover.Profiler/ProfilerCommunication.cpp +++ b/main/OpenCover.Profiler/ProfilerCommunication.cpp @@ -13,13 +13,16 @@ #include #define ONERROR_GOEXIT(hr) if (FAILED(hr)) goto Exit -#define COMM_WAIT_SHORT 10000 -#define COMM_WAIT_LONG 60000 -#define COMM_WAIT_VSHORT 3000 +#define COM_WAIT_LONG 60000 +#define COM_WAIT_VSHORT 3000 -ProfilerCommunication::ProfilerCommunication() +ProfilerCommunication::ProfilerCommunication(DWORD short_wait) { - m_bufferId = 0; + _bufferId = 0; + _pMSG = nullptr; + _pVisitPoints = nullptr; + _hostCommunicationActive = false; + _short_wait = short_wait; } ProfilerCommunication::~ProfilerCommunication() @@ -28,62 +31,62 @@ ProfilerCommunication::~ProfilerCommunication() bool ProfilerCommunication::Initialise(TCHAR *key, TCHAR *ns, TCHAR *processName) { - m_key = key; - m_processName = processName; + _key = key; + _processName = processName; std::wstring sharedKey = key; sharedKey.append(_T("-1")); - m_namespace = ns; + _namespace = ns; - m_mutexCommunication.Initialise((m_namespace + _T("\\OpenCover_Profiler_Communication_Mutex_") + m_key).c_str()); - if (!m_mutexCommunication.IsValid()) return false; + _mutexCommunication.Initialise((_namespace + _T("\\OpenCover_Profiler_Communication_Mutex_") + _key).c_str()); + if (!_mutexCommunication.IsValid()) return false; USES_CONVERSION; - ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised mutexes => %s"), W2CT(sharedKey.c_str())); + ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised mutexes => %s\n"), W2CT(sharedKey.c_str())); - auto resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_SendData_Event_") + sharedKey); - m_eventProfilerRequestsInformation.Initialise(resource_name.c_str()); - if (!m_eventProfilerRequestsInformation.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); + auto resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_SendData_Event_") + sharedKey); + _eventProfilerRequestsInformation.Initialise(resource_name.c_str()); + if (!_eventProfilerRequestsInformation.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_ChunkData_Event_") + sharedKey); - m_eventInformationReadByProfiler.Initialise(resource_name.c_str()); - if (!m_eventInformationReadByProfiler.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) = >Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_ChunkData_Event_") + sharedKey); + _eventInformationReadByProfiler.Initialise(resource_name.c_str()); + if (!_eventInformationReadByProfiler.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) = >Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_ReceiveData_Event_") + sharedKey); - m_eventInformationReadyForProfiler.Initialise(resource_name.c_str()); - if (!m_eventInformationReadyForProfiler.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_ReceiveData_Event_") + sharedKey); + _eventInformationReadyForProfiler.Initialise(resource_name.c_str()); + if (!_eventInformationReadyForProfiler.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_MemoryMapFile_") + sharedKey); - m_memoryCommunication.OpenFileMapping(resource_name.c_str()); - if (!m_memoryCommunication.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_MemoryMapFile_") + sharedKey); + _memoryCommunication.OpenFileMapping(resource_name.c_str()); + if (!_memoryCommunication.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_Semaphore_") + sharedKey); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_Semaphore_") + sharedKey); _semapore_communication.Initialise(resource_name.c_str()); if (!_semapore_communication.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); return false; } - m_pMSG = (MSG_Union*)m_memoryCommunication.MapViewOfFile(0, 0, MAX_MSG_SIZE); + _pMSG = static_cast(_memoryCommunication.MapViewOfFile(0, 0, MAX_MSG_SIZE)); - hostCommunicationActive = true; + _hostCommunicationActive = true; - ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised communication interface => %s"), W2CT(sharedKey.c_str())); + ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised communication interface => %s\n"), W2CT(sharedKey.c_str())); if (!TrackProcess()){ - RELTRACE(_T("ProfilerCommunication::Initialise(...) => ProfilerCommunication => process is not be tracked")); + RELTRACE(_T("ProfilerCommunication::Initialise(...) => ProfilerCommunication => process is not be tracked\n")); return false; } @@ -95,216 +98,212 @@ bool ProfilerCommunication::Initialise(TCHAR *key, TCHAR *ns, TCHAR *processName stream << bufferId; stream >> memoryKey; - m_bufferId = bufferId; + _bufferId = bufferId; - memoryKey = m_key + memoryKey; + memoryKey = _key + memoryKey; - ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Re-initialising communication interface => %s"), W2CT(memoryKey.c_str())); + ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Re-initialising communication interface => %s\n"), W2CT(memoryKey.c_str())); - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_SendData_Event_") + memoryKey); - m_eventProfilerRequestsInformation.Initialise(resource_name.c_str()); - if (!m_eventProfilerRequestsInformation.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_SendData_Event_") + memoryKey); + _eventProfilerRequestsInformation.Initialise(resource_name.c_str()); + if (!_eventProfilerRequestsInformation.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_ChunkData_Event_") + memoryKey); - m_eventInformationReadByProfiler.Initialise(resource_name.c_str()); - if (!m_eventInformationReadByProfiler.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_ChunkData_Event_") + memoryKey); + _eventInformationReadByProfiler.Initialise(resource_name.c_str()); + if (!_eventInformationReadByProfiler.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_ReceiveData_Event_") + memoryKey); - m_eventInformationReadyForProfiler.Initialise(resource_name.c_str()); - if (!m_eventInformationReadyForProfiler.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_ReceiveData_Event_") + memoryKey); + _eventInformationReadyForProfiler.Initialise(resource_name.c_str()); + if (!_eventInformationReadyForProfiler.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_MemoryMapFile_") + memoryKey); - m_memoryCommunication.OpenFileMapping(resource_name.c_str()); - if (!m_memoryCommunication.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_MemoryMapFile_") + memoryKey); + _memoryCommunication.OpenFileMapping(resource_name.c_str()); + if (!_memoryCommunication.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - m_pMSG = (MSG_Union*)m_memoryCommunication.MapViewOfFile(0, 0, MAX_MSG_SIZE); + _pMSG = static_cast(_memoryCommunication.MapViewOfFile(0, 0, MAX_MSG_SIZE)); - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Communication_Semaphore_") + memoryKey); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Communication_Semaphore_") + memoryKey); _semapore_communication.Initialise(resource_name.c_str()); if (!_semapore_communication.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Re-initialised communication interface => %s"), W2CT(memoryKey.c_str())); + ATLTRACE(_T("ProfilerCommunication::Initialise(...) => Re-initialised communication interface => %s\n"), W2CT(memoryKey.c_str())); - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Results_SendResults_Event_") + memoryKey); - m_eventProfilerHasResults.Initialise(resource_name.c_str()); - if (!m_eventProfilerHasResults.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Results_SendResults_Event_") + memoryKey); + _eventProfilerHasResults.Initialise(resource_name.c_str()); + if (!_eventProfilerHasResults.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Results_ReceiveResults_Event_") + memoryKey); - m_eventResultsHaveBeenReceived.Initialise(resource_name.c_str()); - if (!m_eventResultsHaveBeenReceived.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Results_ReceiveResults_Event_") + memoryKey); + _eventResultsHaveBeenReceived.Initialise(resource_name.c_str()); + if (!_eventResultsHaveBeenReceived.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Results_MemoryMapFile_") + memoryKey); - m_memoryResults.OpenFileMapping(resource_name.c_str()); - if (!m_memoryResults.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + resource_name = (_namespace + _T("\\OpenCover_Profiler_Results_MemoryMapFile_") + memoryKey); + _memoryResults.OpenFileMapping(resource_name.c_str()); + if (!_memoryResults.IsValid()) { + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - m_pVisitPoints = (MSG_SendVisitPoints_Request*)m_memoryResults.MapViewOfFile(0, 0, MAX_MSG_SIZE); + _pVisitPoints = static_cast(_memoryResults.MapViewOfFile(0, 0, MAX_MSG_SIZE)); - m_pVisitPoints->count = 0; + _pVisitPoints->count = 0; - resource_name = (m_namespace + _T("\\OpenCover_Profiler_Results_Semaphore_") + memoryKey); + resource_name = (_namespace + _T("\\OpenCover_Profiler_Results_Semaphore_") + memoryKey); _semapore_results.Initialise(resource_name.c_str()); if (!_semapore_results.IsValid()) { - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d"), W2CT(resource_name.c_str()), ::GetLastError()); - hostCommunicationActive = false; + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Failed to initialise resource %s => ::GetLastError() = %d\n"), W2CT(resource_name.c_str()), ::GetLastError()); + _hostCommunicationActive = false; return false; } - RELTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised results interface => %s"), W2CT(memoryKey.c_str())); + RELTRACE(_T("ProfilerCommunication::Initialise(...) => Initialised results interface => %s\n"), W2CT(memoryKey.c_str())); } else { - hostCommunicationActive = false; + _hostCommunicationActive = false; } - return hostCommunicationActive; + return _hostCommunicationActive; } void ProfilerCommunication::ThreadCreated(ThreadID threadID, DWORD osThreadID){ - ATL::CComCritSecLock lock(m_critThreads); - m_threadmap[threadID] = osThreadID; + _threadmap[threadID] = osThreadID; AllocateVisitMap(osThreadID); } MSG_SendVisitPoints_Request* ProfilerCommunication::AllocateVisitMap(DWORD osThreadID){ - auto p = new MSG_SendVisitPoints_Request(); - p->count = 0; - //::ZeroMemory(p, sizeof(MSG_SendVisitPoints_Request)); - m_visitmap[osThreadID] = p; - return p; + ATL::CComCritSecLock lock(_critThreads); + auto it = _visitmap.find(osThreadID); + if (it == _visitmap.end() || it->second == nullptr) + { + auto p = new MSG_SendVisitPoints_Request(); + p->count = 0; + _visitmap[osThreadID] = p; + return p; + } + return it->second; } MSG_SendVisitPoints_Request* ProfilerCommunication::GetVisitMapForOSThread(ULONG osThreadID){ - MSG_SendVisitPoints_Request * p = NULL; - try { - p = m_visitmap[osThreadID]; - if (p == NULL) - p = AllocateVisitMap(osThreadID); - } - catch (...){ - p = AllocateVisitMap(osThreadID); + auto it = _visitmap.find(osThreadID); + if (it == _visitmap.end() || it->second == nullptr) { + return AllocateVisitMap(osThreadID); } - return p; + return it->second; } void ProfilerCommunication::ThreadDestroyed(ThreadID threadID){ - ATL::CComCritSecLock lock(m_critThreads); - ULONG osThreadId = m_threadmap[threadID]; - auto points = m_visitmap[osThreadId]; + ATL::CComCritSecLock lock(_critThreads); + auto osThreadId = _threadmap[threadID]; + auto points = _visitmap[osThreadId]; SendThreadVisitPoints(points); - delete m_visitmap[osThreadId]; - m_visitmap[osThreadId] = NULL; + delete _visitmap[osThreadId]; + _visitmap[osThreadId] = nullptr; } void ProfilerCommunication::SendRemainingThreadBuffers(){ - ATL::CComCritSecLock lock(m_critThreads); - for (auto it = m_visitmap.begin(); it != m_visitmap.end(); ++it){ - if (it->second != NULL){ + for (auto it = _visitmap.begin(); it != _visitmap.end(); ++it){ + if (it->second != nullptr){ SendThreadVisitPoints(it->second); - //::ZeroMemory(pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); } } } void ProfilerCommunication::AddVisitPointToThreadBuffer(ULONG uniqueId, MSG_IdType msgType) { - DWORD osThreadId = ::GetCurrentThreadId(); + auto osThreadId = ::GetCurrentThreadId(); auto pVisitPoints = GetVisitMapForOSThread(osThreadId); pVisitPoints->points[pVisitPoints->count].UniqueId = (uniqueId | msgType); if (++pVisitPoints->count == VP_BUFFER_SIZE) { SendThreadVisitPoints(pVisitPoints); - //::ZeroMemory(pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); } } void ProfilerCommunication::SendThreadVisitPoints(MSG_SendVisitPoints_Request* pVisitPoints){ - ATL::CComCritSecLock lock(m_critResults); + ATL::CComCritSecLock lock(_critResults); - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return; if (!TestSemaphore(_semapore_results)) return; handle_exception([=](){ - memcpy(m_pVisitPoints, pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); + memcpy(_pVisitPoints, pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); }, _T("SendThreadVisitPoints")); pVisitPoints->count = 0; SendVisitPoints(); - //::ZeroMemory(m_pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); - m_pVisitPoints->count = 0; + //::ZeroMemory(_pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); + _pVisitPoints->count = 0; } void ProfilerCommunication::AddVisitPointToBuffer(ULONG uniqueId, MSG_IdType msgType) { - ATL::CComCritSecLock lock(m_critResults); + ATL::CComCritSecLock lock(_critResults); - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return; if (!TestSemaphore(_semapore_results)) return; handle_exception([=](){ - m_pVisitPoints->points[m_pVisitPoints->count].UniqueId = (uniqueId | msgType); + _pVisitPoints->points[_pVisitPoints->count].UniqueId = (uniqueId | msgType); }, _T("AddVisitPointToBuffer")); - if (++m_pVisitPoints->count == VP_BUFFER_SIZE) + if (++_pVisitPoints->count == VP_BUFFER_SIZE) { SendVisitPoints(); - //::ZeroMemory(m_pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); + //::ZeroMemory(_pVisitPoints, sizeof(MSG_SendVisitPoints_Request)); handle_exception([=](){ - m_pVisitPoints->count = 0; + _pVisitPoints->count = 0; }, _T("AddVisitPointToBuffer")); } } void ProfilerCommunication::SendVisitPoints() { - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return; try { - m_memoryResults.FlushViewOfFile(); + _memoryResults.FlushViewOfFile(); - DWORD dwSignal = m_eventProfilerHasResults.SignalAndWait(m_eventResultsHaveBeenReceived, COMM_WAIT_SHORT); - if (WAIT_OBJECT_0 != dwSignal) throw CommunicationException(dwSignal, COMM_WAIT_SHORT); - m_eventResultsHaveBeenReceived.Reset(); + DWORD dwSignal = _eventProfilerHasResults.SignalAndWait(_eventResultsHaveBeenReceived, _short_wait); + if (WAIT_OBJECT_0 != dwSignal) throw CommunicationException(dwSignal, _short_wait); + _eventResultsHaveBeenReceived.Reset(); } catch (CommunicationException ex) { - RELTRACE(_T("ProfilerCommunication::SendVisitPoints() => Communication (Results channel) with host has failed (0x%x, %d)"), + RELTRACE(_T("ProfilerCommunication::SendVisitPoints() => Communication (Results channel) with host has failed (0x%x, %d)\n"), ex.getReason(), ex.getTimeout()); - hostCommunicationActive = false; + _hostCommunicationActive = false; } return; } @@ -326,35 +325,35 @@ bool ProfilerCommunication::GetPoints(mdToken functionToken, WCHAR* pModulePath, bool ProfilerCommunication::GetSequencePoints(mdToken functionToken, WCHAR* pModulePath, WCHAR* pAssemblyName, std::vector &points) { - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; RequestInformation( [=] { - m_pMSG->getSequencePointsRequest.type = MSG_GetSequencePoints; - m_pMSG->getSequencePointsRequest.functionToken = functionToken; + _pMSG->getSequencePointsRequest.type = MSG_GetSequencePoints; + _pMSG->getSequencePointsRequest.functionToken = functionToken; USES_CONVERSION; - wcscpy_s(m_pMSG->getSequencePointsRequest.szProcessName, T2CW(m_processName.c_str())); - wcscpy_s(m_pMSG->getSequencePointsRequest.szModulePath, pModulePath); - wcscpy_s(m_pMSG->getSequencePointsRequest.szAssemblyName, pAssemblyName); + wcscpy_s(_pMSG->getSequencePointsRequest.szProcessName, T2CW(_processName.c_str())); + wcscpy_s(_pMSG->getSequencePointsRequest.szModulePath, pModulePath); + wcscpy_s(_pMSG->getSequencePointsRequest.szAssemblyName, pAssemblyName); }, [=, &points]()->BOOL { - if (m_pMSG->getSequencePointsResponse.count > SEQ_BUFFER_SIZE){ - RELTRACE(_T("Received an abnormal count for sequence points (%d) for token 0x%X"), - m_pMSG->getSequencePointsResponse.count, functionToken); + if (_pMSG->getSequencePointsResponse.count > SEQ_BUFFER_SIZE){ + RELTRACE(_T("Received an abnormal count for sequence points (%d) for token 0x%X\n"), + _pMSG->getSequencePointsResponse.count, functionToken); points.clear(); return false; } - for (int i = 0; i < m_pMSG->getSequencePointsResponse.count; i++) - points.push_back(m_pMSG->getSequencePointsResponse.points[i]); - BOOL hasMore = m_pMSG->getSequencePointsResponse.hasMore; - ::ZeroMemory(m_pMSG, MAX_MSG_SIZE); + for (int i = 0; i < _pMSG->getSequencePointsResponse.count; i++) + points.push_back(_pMSG->getSequencePointsResponse.points[i]); + BOOL hasMore = _pMSG->getSequencePointsResponse.hasMore; + ::ZeroMemory(_pMSG, MAX_MSG_SIZE); return hasMore; } - , COMM_WAIT_SHORT + , _short_wait , _T("GetSequencePoints")); return (points.size() != 0); @@ -363,35 +362,35 @@ bool ProfilerCommunication::GetSequencePoints(mdToken functionToken, WCHAR* pMod bool ProfilerCommunication::GetBranchPoints(mdToken functionToken, WCHAR* pModulePath, WCHAR* pAssemblyName, std::vector &points) { - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; RequestInformation( [=] { - m_pMSG->getBranchPointsRequest.type = MSG_GetBranchPoints; - m_pMSG->getBranchPointsRequest.functionToken = functionToken; + _pMSG->getBranchPointsRequest.type = MSG_GetBranchPoints; + _pMSG->getBranchPointsRequest.functionToken = functionToken; USES_CONVERSION; - wcscpy_s(m_pMSG->getBranchPointsRequest.szProcessName, T2CW(m_processName.c_str())); - wcscpy_s(m_pMSG->getBranchPointsRequest.szModulePath, pModulePath); - wcscpy_s(m_pMSG->getBranchPointsRequest.szAssemblyName, pAssemblyName); + wcscpy_s(_pMSG->getBranchPointsRequest.szProcessName, T2CW(_processName.c_str())); + wcscpy_s(_pMSG->getBranchPointsRequest.szModulePath, pModulePath); + wcscpy_s(_pMSG->getBranchPointsRequest.szAssemblyName, pAssemblyName); }, [=, &points]()->BOOL { - if (m_pMSG->getBranchPointsResponse.count > BRANCH_BUFFER_SIZE){ - RELTRACE(_T("Received an abnormal count for branch points (%d) for token 0x%X"), - m_pMSG->getBranchPointsResponse.count, functionToken); + if (_pMSG->getBranchPointsResponse.count > BRANCH_BUFFER_SIZE){ + RELTRACE(_T("Received an abnormal count for branch points (%d) for token 0x%X\n"), + _pMSG->getBranchPointsResponse.count, functionToken); points.clear(); return false; } - for (int i=0; i < m_pMSG->getBranchPointsResponse.count;i++) - points.push_back(m_pMSG->getBranchPointsResponse.points[i]); - BOOL hasMore = m_pMSG->getBranchPointsResponse.hasMore; - ::ZeroMemory(m_pMSG, MAX_MSG_SIZE); + for (int i=0; i < _pMSG->getBranchPointsResponse.count;i++) + points.push_back(_pMSG->getBranchPointsResponse.points[i]); + BOOL hasMore = _pMSG->getBranchPointsResponse.hasMore; + ::ZeroMemory(_pMSG, MAX_MSG_SIZE); return hasMore; } - , COMM_WAIT_SHORT + , _short_wait , _T("GetBranchPoints")); return (points.size() != 0); @@ -399,26 +398,26 @@ bool ProfilerCommunication::GetBranchPoints(mdToken functionToken, WCHAR* pModul bool ProfilerCommunication::TrackAssembly(WCHAR* pModulePath, WCHAR* pAssemblyName) { - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; bool response = false; RequestInformation( [=]() { - m_pMSG->trackAssemblyRequest.type = MSG_TrackAssembly; + _pMSG->trackAssemblyRequest.type = MSG_TrackAssembly; USES_CONVERSION; - wcscpy_s(m_pMSG->trackAssemblyRequest.szProcessName, T2CW(m_processName.c_str())); - wcscpy_s(m_pMSG->trackAssemblyRequest.szModulePath, pModulePath); - wcscpy_s(m_pMSG->trackAssemblyRequest.szAssemblyName, pAssemblyName); + wcscpy_s(_pMSG->trackAssemblyRequest.szProcessName, T2CW(_processName.c_str())); + wcscpy_s(_pMSG->trackAssemblyRequest.szModulePath, pModulePath); + wcscpy_s(_pMSG->trackAssemblyRequest.szAssemblyName, pAssemblyName); }, [=, &response]()->BOOL { - response = m_pMSG->trackAssemblyResponse.bResponse == TRUE; - ::ZeroMemory(m_pMSG, MAX_MSG_SIZE); + response = _pMSG->trackAssemblyResponse.bResponse == TRUE; + ::ZeroMemory(_pMSG, MAX_MSG_SIZE); return FALSE; } - , COMM_WAIT_LONG + , COM_WAIT_LONG , _T("TrackAssembly")); return response; @@ -426,26 +425,26 @@ bool ProfilerCommunication::TrackAssembly(WCHAR* pModulePath, WCHAR* pAssemblyNa bool ProfilerCommunication::TrackMethod(mdToken functionToken, WCHAR* pModulePath, WCHAR* pAssemblyName, ULONG &uniqueId) { - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; bool response = false; RequestInformation( [=]() { - m_pMSG->trackMethodRequest.type = MSG_TrackMethod; - m_pMSG->trackMethodRequest.functionToken = functionToken; - wcscpy_s(m_pMSG->trackMethodRequest.szModulePath, pModulePath); - wcscpy_s(m_pMSG->trackMethodRequest.szAssemblyName, pAssemblyName); + _pMSG->trackMethodRequest.type = MSG_TrackMethod; + _pMSG->trackMethodRequest.functionToken = functionToken; + wcscpy_s(_pMSG->trackMethodRequest.szModulePath, pModulePath); + wcscpy_s(_pMSG->trackMethodRequest.szAssemblyName, pAssemblyName); }, [=, &response, &uniqueId]()->BOOL { - response = m_pMSG->trackMethodResponse.bResponse == TRUE; - uniqueId = m_pMSG->trackMethodResponse.ulUniqueId; - ::ZeroMemory(m_pMSG, MAX_MSG_SIZE); + response = _pMSG->trackMethodResponse.bResponse == TRUE; + uniqueId = _pMSG->trackMethodResponse.ulUniqueId; + ::ZeroMemory(_pMSG, MAX_MSG_SIZE); return FALSE; } - , COMM_WAIT_SHORT + , _short_wait , _T("TrackMethod")); return response; @@ -453,29 +452,29 @@ bool ProfilerCommunication::TrackMethod(mdToken functionToken, WCHAR* pModulePat bool ProfilerCommunication::AllocateBuffer(LONG bufferSize, ULONG &bufferId) { - CScopedLock lock(m_mutexCommunication); + CScopedLock lock(_mutexCommunication); - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; bool response = false; int repeat = 0; while (!response && (++repeat <= 3)){ - hostCommunicationActive = true; + _hostCommunicationActive = true; RequestInformation( [=]() { - m_pMSG->allocateBufferRequest.type = MSG_AllocateMemoryBuffer; - m_pMSG->allocateBufferRequest.lBufferSize = bufferSize; + _pMSG->allocateBufferRequest.type = MSG_AllocateMemoryBuffer; + _pMSG->allocateBufferRequest.lBufferSize = bufferSize; }, [=, &response, &bufferId]()->BOOL { - response = m_pMSG->allocateBufferResponse.bResponse == TRUE; - bufferId = m_pMSG->allocateBufferResponse.ulBufferId; - ::ZeroMemory(m_pMSG, MAX_MSG_SIZE); + response = _pMSG->allocateBufferResponse.bResponse == TRUE; + bufferId = _pMSG->allocateBufferResponse.ulBufferId; + ::ZeroMemory(_pMSG, MAX_MSG_SIZE); return FALSE; } - , COMM_WAIT_VSHORT + , COM_WAIT_VSHORT , _T("AllocateBuffer")); } @@ -483,10 +482,10 @@ bool ProfilerCommunication::AllocateBuffer(LONG bufferSize, ULONG &bufferId) } void ProfilerCommunication::CloseChannel(bool sendSingleBuffer){ - if (m_bufferId == 0) + if (_bufferId == 0) return; - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return; if (!TestSemaphore(_semapore_results)) @@ -497,7 +496,7 @@ void ProfilerCommunication::CloseChannel(bool sendSingleBuffer){ else SendRemainingThreadBuffers(); - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return; bool response = false; @@ -505,24 +504,24 @@ void ProfilerCommunication::CloseChannel(bool sendSingleBuffer){ RequestInformation( [=]() { - m_pMSG->closeChannelRequest.type = MSG_CloseChannel; - m_pMSG->closeChannelRequest.ulBufferId = m_bufferId; + _pMSG->closeChannelRequest.type = MSG_CloseChannel; + _pMSG->closeChannelRequest.ulBufferId = _bufferId; }, [=, &response]()->BOOL { - response = m_pMSG->allocateBufferResponse.bResponse == TRUE; + response = _pMSG->allocateBufferResponse.bResponse == TRUE; return FALSE; } - , COMM_WAIT_SHORT + , _short_wait , _T("CloseChannel")); return; } bool ProfilerCommunication::TrackProcess(){ - CScopedLock lock(m_mutexCommunication); + CScopedLock lock(_mutexCommunication); - if (!hostCommunicationActive) + if (!_hostCommunicationActive) return false; bool response = false; @@ -530,16 +529,16 @@ bool ProfilerCommunication::TrackProcess(){ RequestInformation( [=]() { - m_pMSG->trackProcessRequest.type = MSG_TrackProcess; + _pMSG->trackProcessRequest.type = MSG_TrackProcess; USES_CONVERSION; - wcscpy_s(m_pMSG->trackProcessRequest.szProcessName, T2CW(m_processName.c_str())); + wcscpy_s(_pMSG->trackProcessRequest.szProcessName, T2CW(_processName.c_str())); }, [=, &response]()->BOOL { - response = m_pMSG->trackProcessResponse.bResponse == TRUE; + response = _pMSG->trackProcessResponse.bResponse == TRUE; return FALSE; } - , COMM_WAIT_SHORT + , _short_wait , _T("TrackProcess")); return response; @@ -547,12 +546,12 @@ bool ProfilerCommunication::TrackProcess(){ void ProfilerCommunication::report_runtime(const std::runtime_error& re, const tstring &msg){ USES_CONVERSION; - RELTRACE(_T("Runtime error: %s - %s"), msg.c_str(), A2T(re.what())); + RELTRACE(_T("Runtime error: %s - %s\n"), msg.c_str(), A2T(re.what())); } void ProfilerCommunication::report_exception(const std::exception& re, const tstring &msg){ USES_CONVERSION; - RELTRACE(_T("Error occurred: %s - %s"), msg.c_str(), A2T(re.what())); + RELTRACE(_T("Error occurred: %s - %s\n"), msg.c_str(), A2T(re.what())); } template @@ -562,7 +561,7 @@ void ProfilerCommunication::handle_sehexception(Action action, const tstring& me } __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { - RELTRACE(_T("SEH exception failure occured: %s - %d"), + RELTRACE(_T("SEH exception failure occured: %s - %d\n"), message.c_str(), GetExceptionCode()); } } @@ -591,7 +590,7 @@ void ProfilerCommunication::handle_exception(Action action, const tstring& messa catch (...) { // catch any other errors (that we have no information about) - RELTRACE(_T("Unknown failure occured. Possible memory corruption - %s"), message.c_str()); + RELTRACE(_T("Unknown failure occured. Possible memory corruption - %s\n"), message.c_str()); throw; } } @@ -599,8 +598,8 @@ void ProfilerCommunication::handle_exception(Action action, const tstring& messa template void ProfilerCommunication::RequestInformation(BR buildRequest, PR processResults, DWORD dwTimeout, tstring message) { - ATL::CComCritSecLock lock(m_critComms); - if (!hostCommunicationActive) + ATL::CComCritSecLock lock(_critComms); + if (!_hostCommunicationActive) return; if (!TestSemaphore(_semapore_communication)) @@ -610,12 +609,12 @@ void ProfilerCommunication::RequestInformation(BR buildRequest, PR processResult handle_exception([&](){ buildRequest(); }, message); - m_memoryCommunication.FlushViewOfFile(); + _memoryCommunication.FlushViewOfFile(); - DWORD dwSignal = m_eventProfilerRequestsInformation.SignalAndWait(m_eventInformationReadyForProfiler, dwTimeout); + DWORD dwSignal = _eventProfilerRequestsInformation.SignalAndWait(_eventInformationReadyForProfiler, dwTimeout); if (WAIT_OBJECT_0 != dwSignal) throw CommunicationException(dwSignal, dwTimeout); - m_eventInformationReadyForProfiler.Reset(); + _eventInformationReadyForProfiler.Reset(); BOOL hasMore = FALSE; do @@ -624,21 +623,21 @@ void ProfilerCommunication::RequestInformation(BR buildRequest, PR processResult if (hasMore) { - dwSignal = m_eventInformationReadByProfiler.SignalAndWait(m_eventInformationReadyForProfiler, COMM_WAIT_SHORT); - if (WAIT_OBJECT_0 != dwSignal) throw CommunicationException(dwSignal, COMM_WAIT_SHORT); + dwSignal = _eventInformationReadByProfiler.SignalAndWait(_eventInformationReadyForProfiler, _short_wait); + if (WAIT_OBJECT_0 != dwSignal) throw CommunicationException(dwSignal, _short_wait); - m_eventInformationReadyForProfiler.Reset(); + _eventInformationReadyForProfiler.Reset(); } }while (hasMore); - m_eventInformationReadByProfiler.Set(); + _eventInformationReadByProfiler.Set(); } catch (CommunicationException ex) { - RELTRACE(_T("ProfilerCommunication::RequestInformation(...) => Communication (Chat channel - %s) with host has failed (0x%x, %d)"), + RELTRACE(_T("ProfilerCommunication::RequestInformation(...) => Communication (Chat channel - %s) with host has failed (0x%x, %d)\n"), message.c_str(), ex.getReason(), ex.getTimeout()); - hostCommunicationActive = false; + _hostCommunicationActive = false; } catch (...) { - hostCommunicationActive = false; + _hostCommunicationActive = false; } } diff --git a/main/OpenCover.Profiler/ProfilerCommunication.h b/main/OpenCover.Profiler/ProfilerCommunication.h index 703946720..04759ce92 100644 --- a/main/OpenCover.Profiler/ProfilerCommunication.h +++ b/main/OpenCover.Profiler/ProfilerCommunication.h @@ -10,9 +10,8 @@ #include "Messages.h" #include -#include -#include +#include /// Handles communication back to the profiler host /// Currently this is handled by using the WebServices API @@ -21,7 +20,7 @@ class ProfilerCommunication private: public: - ProfilerCommunication(); + ProfilerCommunication(DWORD short_wait); ~ProfilerCommunication(void); bool Initialise(TCHAR* key, TCHAR *ns, TCHAR *processName); @@ -54,49 +53,53 @@ class ProfilerCommunication MSG_SendVisitPoints_Request* AllocateVisitMap(DWORD osThreadID); private: - tstring m_key; - tstring m_namespace; - tstring m_processName; + tstring _key; + tstring _namespace; + tstring _processName; + DWORD _short_wait; template void RequestInformation(BR buildRequest, PR processResults, DWORD dwTimeout, tstring message); - ULONG m_bufferId; + ULONG _bufferId; bool TestSemaphore(CSemaphoreEx &semaphore){ // the previous value should always be zero unless the host process has released // and that means we have disposed of the shared memory - if (hostCommunicationActive && semaphore.ReleaseAndWait() != 0) { - hostCommunicationActive = false; + if (_hostCommunicationActive && semaphore.ReleaseAndWait() != 0) { + _hostCommunicationActive = false; } - return hostCommunicationActive; + return _hostCommunicationActive; } private: - CMutex m_mutexCommunication; - CSharedMemory m_memoryCommunication; - CEvent m_eventProfilerRequestsInformation; - CEvent m_eventInformationReadyForProfiler; - CEvent m_eventInformationReadByProfiler; - MSG_Union *m_pMSG; + CMutex _mutexCommunication; + CSharedMemory _memoryCommunication; + CEvent _eventProfilerRequestsInformation; + CEvent _eventInformationReadyForProfiler; + CEvent _eventInformationReadByProfiler; + MSG_Union *_pMSG; CSemaphoreEx _semapore_communication; private: - CSharedMemory m_memoryResults; - CEvent m_eventProfilerHasResults; - CEvent m_eventResultsHaveBeenReceived; - MSG_SendVisitPoints_Request *m_pVisitPoints; + CSharedMemory _memoryResults; + CEvent _eventProfilerHasResults; + CEvent _eventResultsHaveBeenReceived; + MSG_SendVisitPoints_Request *_pVisitPoints; CSemaphoreEx _semapore_results; private: - ATL::CComAutoCriticalSection m_critResults; - ATL::CComAutoCriticalSection m_critComms; - bool hostCommunicationActive; + ATL::CComAutoCriticalSection _critResults; + ATL::CComAutoCriticalSection _critComms; + bool _hostCommunicationActive; private: - ATL::CComAutoCriticalSection m_critThreads; - std::unordered_map m_threadmap; - std::unordered_map m_visitmap; + ATL::CComAutoCriticalSection _critThreads; + //std::unordered_map _threadmap; + //std::unordered_map _visitmap; + + Concurrency::concurrent_unordered_map _threadmap; + Concurrency::concurrent_unordered_map _visitmap; MSG_SendVisitPoints_Request* GetVisitMapForOSThread(ULONG osThread); diff --git a/main/OpenCover.Profiler/ProfilerInfo.cpp b/main/OpenCover.Profiler/ProfilerInfo.cpp index d879e259f..a57189d6a 100644 --- a/main/OpenCover.Profiler/ProfilerInfo.cpp +++ b/main/OpenCover.Profiler/ProfilerInfo.cpp @@ -18,7 +18,7 @@ HRESULT STDMETHODCALLTYPE CProfilerInfo::SetEventMask( expected |= COR_PRF_MONITOR_MODULE_LOADS; expected |= COR_PRF_ENABLE_REJIT; // VS2012 only - ATLTRACE(_T("CProfilerInfo::SetEventMask => received => 0x%X, expected 0x%X"), dwEvents, expected); + ATLTRACE(_T("CProfilerInfo::SetEventMask => received => 0x%X, expected 0x%X\n"), dwEvents, expected); ATLASSERT(expected == (dwEvents | expected)); // assert that nothing new has been added that we haven't already tested against if (m_pProfilerHook!=NULL) diff --git a/main/OpenCover.Profiler/ProfilerInfo.h b/main/OpenCover.Profiler/ProfilerInfo.h index 17f985e6f..f61c19d46 100644 --- a/main/OpenCover.Profiler/ProfilerInfo.h +++ b/main/OpenCover.Profiler/ProfilerInfo.h @@ -22,6 +22,7 @@ class ATL_NO_VTABLE CProfilerInfo : public: CProfilerInfo() { + m_pProfilerHook = nullptr; } BEGIN_COM_MAP(CProfilerInfo) diff --git a/main/OpenCover.Profiler/ProfilerInfoBase.h b/main/OpenCover.Profiler/ProfilerInfoBase.h index 59465c7ee..c4f38d423 100644 --- a/main/OpenCover.Profiler/ProfilerInfoBase.h +++ b/main/OpenCover.Profiler/ProfilerInfoBase.h @@ -8,7 +8,11 @@ using namespace ATL; class CProfilerInfoBase : public ICorProfilerInfo4 { public: - void SetProfilerInfo(IUnknown *pICorProfilerInfoUnk){ + virtual ~CProfilerInfoBase() + { + } + + void SetProfilerInfo(IUnknown *pICorProfilerInfoUnk){ m_pProfilerInfo = pICorProfilerInfoUnk; m_pProfilerInfo2 = pICorProfilerInfoUnk; m_pProfilerInfo3 = pICorProfilerInfoUnk; @@ -24,59 +28,67 @@ class CProfilerInfoBase : public ICorProfilerInfo4 public: // ICorProfilerInfo virtual HRESULT STDMETHODCALLTYPE GetClassFromObject( /* [in] */ ObjectID objectId, - /* [out] */ ClassID *pClassId){ - //ATLTRACE(_T("GetClassFromObject")); + /* [out] */ ClassID *pClassId) override + { + //ATLTRACE(_T("GetClassFromObject\n")); return m_pProfilerInfo->GetClassFromObject(objectId, pClassId); } virtual HRESULT STDMETHODCALLTYPE GetClassFromToken( /* [in] */ ModuleID moduleId, /* [in] */ mdTypeDef typeDef, - /* [out] */ ClassID *pClassId){ - //ATLTRACE(_T("GetClassFromToken")); + /* [out] */ ClassID *pClassId) override + { + //ATLTRACE(_T("GetClassFromToken\n")); return m_pProfilerInfo->GetClassFromToken(moduleId, typeDef, pClassId); } virtual HRESULT STDMETHODCALLTYPE GetCodeInfo( /* [in] */ FunctionID functionId, /* [out] */ LPCBYTE *pStart, - /* [out] */ ULONG *pcSize){ - //ATLTRACE(_T("GetCodeInfo")); + /* [out] */ ULONG *pcSize) override + { + //ATLTRACE(_T("GetCodeInfo\n")); return m_pProfilerInfo->GetCodeInfo(functionId, pStart, pcSize); } virtual HRESULT STDMETHODCALLTYPE GetEventMask( - /* [out] */ DWORD *pdwEvents){ - //ATLTRACE(_T("GetEventMask")); + /* [out] */ DWORD *pdwEvents) override + { + //ATLTRACE(_T("GetEventMask\n")); return m_pProfilerInfo->GetEventMask(pdwEvents); } virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP( /* [in] */ LPCBYTE ip, - /* [out] */ FunctionID *pFunctionId){ - //ATLTRACE(_T("GetFunctionFromIP")); + /* [out] */ FunctionID *pFunctionId) override + { + //ATLTRACE(_T("GetFunctionFromIP\n")); return m_pProfilerInfo->GetFunctionFromIP(ip, pFunctionId); } virtual HRESULT STDMETHODCALLTYPE GetFunctionFromToken( /* [in] */ ModuleID moduleId, /* [in] */ mdToken token, - /* [out] */ FunctionID *pFunctionId){ - //ATLTRACE(_T("GetFunctionFromToken")); + /* [out] */ FunctionID *pFunctionId) override + { + //ATLTRACE(_T("GetFunctionFromToken\n")); return m_pProfilerInfo->GetFunctionFromToken(moduleId, token, pFunctionId); } virtual HRESULT STDMETHODCALLTYPE GetHandleFromThread( /* [in] */ ThreadID threadId, - /* [out] */ HANDLE *phThread){ - //ATLTRACE(_T("GetHandleFromThread")); + /* [out] */ HANDLE *phThread) override + { + //ATLTRACE(_T("GetHandleFromThread\n")); return m_pProfilerInfo->GetHandleFromThread(threadId, phThread); } virtual HRESULT STDMETHODCALLTYPE GetObjectSize( /* [in] */ ObjectID objectId, - /* [out] */ ULONG *pcSize){ - //ATLTRACE(_T("GetObjectSize")); + /* [out] */ ULONG *pcSize) override + { + //ATLTRACE(_T("GetObjectSize\n")); return m_pProfilerInfo->GetObjectSize(objectId, pcSize); } @@ -84,29 +96,33 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ClassID classId, /* [out] */ CorElementType *pBaseElemType, /* [out] */ ClassID *pBaseClassId, - /* [out] */ ULONG *pcRank){ - //ATLTRACE(_T("IsArrayClass")); + /* [out] */ ULONG *pcRank) override + { + //ATLTRACE(_T("IsArrayClass\n")); return m_pProfilerInfo->IsArrayClass(classId, pBaseElemType, pBaseClassId, pcRank); } virtual HRESULT STDMETHODCALLTYPE GetThreadInfo( /* [in] */ ThreadID threadId, - /* [out] */ DWORD *pdwWin32ThreadId){ - //ATLTRACE(_T("GetThreadInfo")); + /* [out] */ DWORD *pdwWin32ThreadId) override + { + //ATLTRACE(_T("GetThreadInfo\n")); return m_pProfilerInfo->GetThreadInfo(threadId, pdwWin32ThreadId); } virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadID( - /* [out] */ ThreadID *pThreadId){ - //ATLTRACE(_T("GetCurrentThreadID")); + /* [out] */ ThreadID *pThreadId) override + { + //ATLTRACE(_T("GetCurrentThreadID\n")); return m_pProfilerInfo->GetCurrentThreadID(pThreadId); } virtual HRESULT STDMETHODCALLTYPE GetClassIDInfo( /* [in] */ ClassID classId, /* [out] */ ModuleID *pModuleId, - /* [out] */ mdTypeDef *pTypeDefToken){ - //ATLTRACE(_T("GetClassIDInfo")); + /* [out] */ mdTypeDef *pTypeDefToken) override + { + //ATLTRACE(_T("GetClassIDInfo\n")); return m_pProfilerInfo->GetClassIDInfo(classId, pModuleId, pTypeDefToken); } @@ -114,28 +130,32 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [out] */ ClassID *pClassId, /* [out] */ ModuleID *pModuleId, - /* [out] */ mdToken *pToken){ - //ATLTRACE(_T("GetFunctionInfo")); + /* [out] */ mdToken *pToken) override + { + //ATLTRACE(_T("GetFunctionInfo\n")); return m_pProfilerInfo->GetFunctionInfo(functionId, pClassId, pModuleId, pToken); } virtual HRESULT STDMETHODCALLTYPE SetEventMask( - /* [in] */ DWORD dwEvents){ - ATLTRACE(_T("CProfilerInfoBase::SetEventMask(0x%X)"), dwEvents); + /* [in] */ DWORD dwEvents) override + { + ATLTRACE(_T("CProfilerInfoBase::SetEventMask(0x%X)\n"), dwEvents); return m_pProfilerInfo->SetEventMask(dwEvents); } virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks( /* [in] */ FunctionEnter *pFuncEnter, /* [in] */ FunctionLeave *pFuncLeave, - /* [in] */ FunctionTailcall *pFuncTailcall){ - //ATLTRACE(_T("SetEnterLeaveFunctionHooks")); + /* [in] */ FunctionTailcall *pFuncTailcall) override + { + //ATLTRACE(_T("SetEnterLeaveFunctionHooks\n")); return m_pProfilerInfo->SetEnterLeaveFunctionHooks(pFuncEnter, pFuncLeave, pFuncTailcall); } virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper( - /* [in] */ FunctionIDMapper *pFunc){ - //ATLTRACE(_T("SetFunctionIDMapper")); + /* [in] */ FunctionIDMapper *pFunc) override + { + //ATLTRACE(_T("SetFunctionIDMapper\n")); return m_pProfilerInfo->SetFunctionIDMapper(pFunc); } @@ -143,8 +163,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppImport, - /* [out] */ mdToken *pToken){ - //ATLTRACE(_T("GetTokenAndMetaDataFromFunction")); + /* [out] */ mdToken *pToken) override + { + //ATLTRACE(_T("GetTokenAndMetaDataFromFunction\n")); return m_pProfilerInfo->GetTokenAndMetaDataFromFunction(functionId, riid, ppImport, pToken); } @@ -155,8 +176,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [out] */ ULONG *pcchName, /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[], - /* [out] */ AssemblyID *pAssemblyId){ - //ATLTRACE(_T("GetModuleInfo")); + /* [out] */ AssemblyID *pAssemblyId) override + { + //ATLTRACE(_T("GetModuleInfo\n")); return m_pProfilerInfo->GetModuleInfo(moduleId, ppBaseLoadAddress, cchName, pcchName, szName, pAssemblyId); } @@ -164,8 +186,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ModuleID moduleId, /* [in] */ DWORD dwOpenFlags, /* [in] */ REFIID riid, - /* [out] */ IUnknown **ppOut){ - //ATLTRACE(_T("GetModuleMetaData")); + /* [out] */ IUnknown **ppOut) override + { + //ATLTRACE(_T("GetModuleMetaData\n")); return m_pProfilerInfo->GetModuleMetaData(moduleId, dwOpenFlags, riid, ppOut); } @@ -173,23 +196,26 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodId, /* [out] */ LPCBYTE *ppMethodHeader, - /* [out] */ ULONG *pcbMethodSize){ - //ATLTRACE(_T("GetILFunctionBody")); + /* [out] */ ULONG *pcbMethodSize) override + { + //ATLTRACE(_T("GetILFunctionBody\n")); return m_pProfilerInfo->GetILFunctionBody(moduleId, methodId, ppMethodHeader, pcbMethodSize); } virtual HRESULT STDMETHODCALLTYPE GetILFunctionBodyAllocator( /* [in] */ ModuleID moduleId, - /* [out] */ IMethodMalloc **ppMalloc){ - //ATLTRACE(_T("GetILFunctionBodyAllocator")); + /* [out] */ IMethodMalloc **ppMalloc) override + { + //ATLTRACE(_T("GetILFunctionBodyAllocator\n")); return m_pProfilerInfo->GetILFunctionBodyAllocator(moduleId, ppMalloc); } virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody( /* [in] */ ModuleID moduleId, /* [in] */ mdMethodDef methodid, - /* [in] */ LPCBYTE pbNewILMethodHeader){ - //ATLTRACE(_T("SetILFunctionBody")); + /* [in] */ LPCBYTE pbNewILMethodHeader) override + { + //ATLTRACE(_T("SetILFunctionBody\n")); return m_pProfilerInfo->SetILFunctionBody(moduleId, methodid, pbNewILMethodHeader); } @@ -199,8 +225,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [out] */ ULONG *pcchName, /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[], - /* [out] */ ProcessID *pProcessId){ - //ATLTRACE(_T("GetAppDomainInfo")); + /* [out] */ ProcessID *pProcessId) override + { + //ATLTRACE(_T("GetAppDomainInfo\n")); return m_pProfilerInfo->GetAppDomainInfo(appDomainId, cchName, pcchName, szName, pProcessId); } @@ -211,19 +238,22 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[], /* [out] */ AppDomainID *pAppDomainId, - /* [out] */ ModuleID *pModuleId){ - //ATLTRACE(_T("GetAssemblyInfo")); + /* [out] */ ModuleID *pModuleId) override + { + //ATLTRACE(_T("GetAssemblyInfo\n")); return m_pProfilerInfo->GetAssemblyInfo(assemblyId, cchName, pcchName, szName, pAppDomainId, pModuleId); } virtual HRESULT STDMETHODCALLTYPE SetFunctionReJIT( - /* [in] */ FunctionID functionId){ - //ATLTRACE(_T("SetFunctionReJIT")); + /* [in] */ FunctionID functionId) override + { + //ATLTRACE(_T("SetFunctionReJIT\n")); return m_pProfilerInfo->SetFunctionReJIT(functionId); } - virtual HRESULT STDMETHODCALLTYPE ForceGC(void){ - //ATLTRACE(_T("GetClassFromObject")); + virtual HRESULT STDMETHODCALLTYPE ForceGC(void) override + { + //ATLTRACE(_T("GetClassFromObject\n")); return m_pProfilerInfo->ForceGC(); } @@ -231,40 +261,46 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [in] */ BOOL fStartJit, /* [in] */ ULONG cILMapEntries, - /* [size_is][in] */ COR_IL_MAP rgILMapEntries[]){ - //ATLTRACE(_T("SetILInstrumentedCodeMap")); + /* [size_is][in] */ COR_IL_MAP rgILMapEntries[]) override + { + //ATLTRACE(_T("SetILInstrumentedCodeMap\n")); return m_pProfilerInfo->SetILInstrumentedCodeMap(functionId, fStartJit, cILMapEntries, rgILMapEntries); } virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionInterface( - /* [out] */ IUnknown **ppicd){ - //ATLTRACE(_T("GetInprocInspectionInterface")); + /* [out] */ IUnknown **ppicd) override + { + //ATLTRACE(_T("GetInprocInspectionInterface\n")); return m_pProfilerInfo->GetInprocInspectionInterface(ppicd); } virtual HRESULT STDMETHODCALLTYPE GetInprocInspectionIThisThread( - /* [out] */ IUnknown **ppicd){ - //ATLTRACE(_T("GetInprocInspectionIThisThread")); + /* [out] */ IUnknown **ppicd) override + { + //ATLTRACE(_T("GetInprocInspectionIThisThread\n")); return m_pProfilerInfo->GetInprocInspectionIThisThread(ppicd); } virtual HRESULT STDMETHODCALLTYPE GetThreadContext( /* [in] */ ThreadID threadId, - /* [out] */ ContextID *pContextId){ - //ATLTRACE(_T("GetThreadContext")); + /* [out] */ ContextID *pContextId) override + { + //ATLTRACE(_T("GetThreadContext\n")); return m_pProfilerInfo->GetThreadContext(threadId, pContextId); } virtual HRESULT STDMETHODCALLTYPE BeginInprocDebugging( /* [in] */ BOOL fThisThreadOnly, - /* [out] */ DWORD *pdwProfilerContext){ - //ATLTRACE(_T("BeginInprocDebugging")); + /* [out] */ DWORD *pdwProfilerContext) override + { + //ATLTRACE(_T("BeginInprocDebugging\n")); return m_pProfilerInfo->BeginInprocDebugging(fThisThreadOnly, pdwProfilerContext); } virtual HRESULT STDMETHODCALLTYPE EndInprocDebugging( - /* [in] */ DWORD dwProfilerContext){ - //ATLTRACE(_T("EndInprocDebugging")); + /* [in] */ DWORD dwProfilerContext) override + { + //ATLTRACE(_T("EndInprocDebugging\n")); return m_pProfilerInfo->EndInprocDebugging(dwProfilerContext); } @@ -272,8 +308,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, - /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[]){ - //ATLTRACE(_T("GetILToNativeMapping")); + /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[]) override + { + //ATLTRACE(_T("GetILToNativeMapping\n")); return m_pProfilerInfo->GetILToNativeMapping(functionId, cMap, pcMap, map); } @@ -284,16 +321,18 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ULONG32 infoFlags, /* [in] */ void *clientData, /* [size_is][in] */ BYTE context[], - /* [in] */ ULONG32 contextSize){ - //ATLTRACE(_T("DoStackSnapshot")); + /* [in] */ ULONG32 contextSize) override + { + //ATLTRACE(_T("DoStackSnapshot\n")); return m_pProfilerInfo2->DoStackSnapshot(thread, callback, infoFlags, clientData, context, contextSize); } virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks2( /* [in] */ FunctionEnter2 *pFuncEnter, /* [in] */ FunctionLeave2 *pFuncLeave, - /* [in] */ FunctionTailcall2 *pFuncTailcall){ - //ATLTRACE(_T("SetEnterLeaveFunctionHooks2")); + /* [in] */ FunctionTailcall2 *pFuncTailcall) override + { + //ATLTRACE(_T("SetEnterLeaveFunctionHooks2\n")); return m_pProfilerInfo2->SetEnterLeaveFunctionHooks2(pFuncEnter, pFuncLeave, pFuncTailcall); } @@ -305,16 +344,18 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [out] */ mdToken *pToken, /* [in] */ ULONG32 cTypeArgs, /* [out] */ ULONG32 *pcTypeArgs, - /* [out] */ ClassID typeArgs[]){ - //ATLTRACE(_T("GetFunctionInfo2")); + /* [out] */ ClassID typeArgs[]) override + { + //ATLTRACE(_T("GetFunctionInfo2\n")); return m_pProfilerInfo2->GetFunctionInfo2(funcId, frameInfo, pClassId, pModuleId, pToken, cTypeArgs, pcTypeArgs, typeArgs); } virtual HRESULT STDMETHODCALLTYPE GetStringLayout( /* [out] */ ULONG *pBufferLengthOffset, /* [out] */ ULONG *pStringLengthOffset, - /* [out] */ ULONG *pBufferOffset){ - //ATLTRACE(_T("GetStringLayout")); + /* [out] */ ULONG *pBufferOffset) override + { + //ATLTRACE(_T("GetStringLayout\n")); return m_pProfilerInfo2->GetStringLayout(pBufferLengthOffset, pStringLengthOffset, pBufferOffset); } @@ -323,8 +364,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[], /* [in] */ ULONG cFieldOffset, /* [out] */ ULONG *pcFieldOffset, - /* [out] */ ULONG *pulClassSize){ - //ATLTRACE(_T("GetClassLayout")); + /* [out] */ ULONG *pulClassSize) override + { + //ATLTRACE(_T("GetClassLayout\n")); return m_pProfilerInfo2->GetClassLayout(classID, rFieldOffset, cFieldOffset, pcFieldOffset, pulClassSize); } @@ -335,8 +377,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [out] */ ClassID *pParentClassId, /* [in] */ ULONG32 cNumTypeArgs, /* [out] */ ULONG32 *pcNumTypeArgs, - /* [out] */ ClassID typeArgs[]){ - //ATLTRACE(_T("GetClassIDInfo2")); + /* [out] */ ClassID typeArgs[]) override + { + //ATLTRACE(_T("GetClassIDInfo2\n")); return m_pProfilerInfo2->GetClassIDInfo2(classId, pModuleId, pTypeDefToken, pParentClassId, cNumTypeArgs, pcNumTypeArgs, typeArgs); } @@ -344,8 +387,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionID, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, - /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[]){ - //ATLTRACE(_T("GetCodeInfo2")); + /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[]) override + { + //ATLTRACE(_T("GetCodeInfo2\n")); return m_pProfilerInfo2->GetCodeInfo2(functionID, cCodeInfos, pcCodeInfos, codeInfos); } @@ -354,8 +398,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ mdTypeDef typeDef, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[], - /* [out] */ ClassID *pClassID){ - //ATLTRACE(_T("GetClassFromTokenAndTypeArgs")); + /* [out] */ ClassID *pClassID) override + { + //ATLTRACE(_T("GetClassFromTokenAndTypeArgs\n")); return m_pProfilerInfo2->GetClassFromTokenAndTypeArgs(moduleID, typeDef, cTypeArgs, typeArgs, pClassID); } @@ -365,15 +410,17 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ClassID classId, /* [in] */ ULONG32 cTypeArgs, /* [size_is][in] */ ClassID typeArgs[], - /* [out] */ FunctionID *pFunctionID){ - //ATLTRACE(_T("GetFunctionFromTokenAndTypeArgs")); + /* [out] */ FunctionID *pFunctionID) override + { + //ATLTRACE(_T("GetFunctionFromTokenAndTypeArgs\n")); return m_pProfilerInfo2->GetFunctionFromTokenAndTypeArgs(moduleID, funcDef, classId, cTypeArgs, typeArgs, pFunctionID); } virtual HRESULT STDMETHODCALLTYPE EnumModuleFrozenObjects( /* [in] */ ModuleID moduleID, - /* [out] */ ICorProfilerObjectEnum **ppEnum){ - //ATLTRACE(_T("GetClassFromObject")); + /* [out] */ ICorProfilerObjectEnum **ppEnum) override + { + //ATLTRACE(_T("GetClassFromObject\n")); return m_pProfilerInfo2->EnumModuleFrozenObjects(moduleID, ppEnum); } @@ -382,30 +429,34 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ULONG32 cDimensions, /* [size_is][out] */ ULONG32 pDimensionSizes[], /* [size_is][out] */ int pDimensionLowerBounds[], - /* [out] */ BYTE **ppData){ - //ATLTRACE(_T("GetArrayObjectInfo")); + /* [out] */ BYTE **ppData) override + { + //ATLTRACE(_T("GetArrayObjectInfo\n")); return m_pProfilerInfo2->GetArrayObjectInfo(objectId, cDimensions, pDimensionSizes, pDimensionLowerBounds, ppData); } virtual HRESULT STDMETHODCALLTYPE GetBoxClassLayout( /* [in] */ ClassID classId, - /* [out] */ ULONG32 *pBufferOffset){ - //ATLTRACE(_T("GetBoxClassLayout")); + /* [out] */ ULONG32 *pBufferOffset) override + { + //ATLTRACE(_T("GetBoxClassLayout\n")); return m_pProfilerInfo2->GetBoxClassLayout(classId, pBufferOffset); } virtual HRESULT STDMETHODCALLTYPE GetThreadAppDomain( /* [in] */ ThreadID threadId, - /* [out] */ AppDomainID *pAppDomainId){ - //ATLTRACE(_T("GetThreadAppDomain")); + /* [out] */ AppDomainID *pAppDomainId) override + { + //ATLTRACE(_T("GetThreadAppDomain\n")); return m_pProfilerInfo2->GetThreadAppDomain(threadId, pAppDomainId); } virtual HRESULT STDMETHODCALLTYPE GetRVAStaticAddress( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, - /* [out] */ void **ppAddress){ - //ATLTRACE(_T("GetRVAStaticAddress")); + /* [out] */ void **ppAddress) override + { + //ATLTRACE(_T("GetRVAStaticAddress\n")); return m_pProfilerInfo2->GetRVAStaticAddress(classId, fieldToken, ppAddress); } @@ -413,8 +464,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, - /* [out] */ void **ppAddress){ - //ATLTRACE(_T("GetAppDomainStaticAddress")); + /* [out] */ void **ppAddress) override + { + //ATLTRACE(_T("GetAppDomainStaticAddress\n")); return m_pProfilerInfo2->GetAppDomainStaticAddress(classId, fieldToken, appDomainId, ppAddress); } @@ -422,8 +474,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ThreadID threadId, - /* [out] */ void **ppAddress){ - //ATLTRACE(_T("GetThreadStaticAddress")); + /* [out] */ void **ppAddress) override + { + //ATLTRACE(_T("GetThreadStaticAddress\n")); return m_pProfilerInfo2->GetThreadStaticAddress(classId, fieldToken, threadId, ppAddress); } @@ -431,80 +484,91 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, /* [in] */ ContextID contextId, - /* [out] */ void **ppAddress){ - //ATLTRACE(_T("GetContextStaticAddress")); + /* [out] */ void **ppAddress) override + { + //ATLTRACE(_T("GetContextStaticAddress\n")); return m_pProfilerInfo2->GetContextStaticAddress(classId, fieldToken, contextId, ppAddress); } virtual HRESULT STDMETHODCALLTYPE GetStaticFieldInfo( /* [in] */ ClassID classId, /* [in] */ mdFieldDef fieldToken, - /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo){ - //ATLTRACE(_T("GetStaticFieldInfo")); + /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo) override + { + //ATLTRACE(_T("GetStaticFieldInfo\n")); return m_pProfilerInfo2->GetStaticFieldInfo(classId, fieldToken, pFieldInfo); } virtual HRESULT STDMETHODCALLTYPE GetGenerationBounds( /* [in] */ ULONG cObjectRanges, /* [out] */ ULONG *pcObjectRanges, - /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[]){ - //ATLTRACE(_T("GetGenerationBounds")); + /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[]) override + { + //ATLTRACE(_T("GetGenerationBounds\n")); return m_pProfilerInfo2->GetGenerationBounds(cObjectRanges, pcObjectRanges, ranges); } virtual HRESULT STDMETHODCALLTYPE GetObjectGeneration( /* [in] */ ObjectID objectId, - /* [out] */ COR_PRF_GC_GENERATION_RANGE *range){ - //ATLTRACE(_T("GetObjectGeneration")); + /* [out] */ COR_PRF_GC_GENERATION_RANGE *range) override + { + //ATLTRACE(_T("GetObjectGeneration\n")); return m_pProfilerInfo2->GetObjectGeneration(objectId, range); } virtual HRESULT STDMETHODCALLTYPE GetNotifiedExceptionClauseInfo( - /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo){ - //ATLTRACE(_T("GetNotifiedExceptionClauseInfo")); + /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo) override + { + //ATLTRACE(_T("GetNotifiedExceptionClauseInfo\n")); return m_pProfilerInfo2->GetNotifiedExceptionClauseInfo(pinfo); } public: // ICorProfilerInfo3 virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions( - /* [out] */ ICorProfilerFunctionEnum **ppEnum){ - //ATLTRACE(_T("EnumJITedFunctions")); + /* [out] */ ICorProfilerFunctionEnum **ppEnum) override + { + //ATLTRACE(_T("EnumJITedFunctions\n")); return m_pProfilerInfo3->EnumJITedFunctions(ppEnum); } virtual HRESULT STDMETHODCALLTYPE RequestProfilerDetach( - /* [in] */ DWORD dwExpectedCompletionMilliseconds){ - //ATLTRACE(_T("RequestProfilerDetach")); + /* [in] */ DWORD dwExpectedCompletionMilliseconds) override + { + //ATLTRACE(_T("RequestProfilerDetach\n")); return m_pProfilerInfo3->RequestProfilerDetach(dwExpectedCompletionMilliseconds); } virtual HRESULT STDMETHODCALLTYPE SetFunctionIDMapper2( /* [in] */ FunctionIDMapper2 *pFunc, - /* [in] */ void *clientData){ - //ATLTRACE(_T("SetFunctionIDMapper2")); + /* [in] */ void *clientData) override + { + //ATLTRACE(_T("SetFunctionIDMapper2\n")); return m_pProfilerInfo3->SetFunctionIDMapper2(pFunc, clientData); } virtual HRESULT STDMETHODCALLTYPE GetStringLayout2( /* [out] */ ULONG *pStringLengthOffset, - /* [out] */ ULONG *pBufferOffset){ - //ATLTRACE(_T("GetStringLayout2")); + /* [out] */ ULONG *pBufferOffset) override + { + //ATLTRACE(_T("GetStringLayout2\n")); return m_pProfilerInfo3->GetStringLayout2(pStringLengthOffset, pBufferOffset); } virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3( /* [in] */ FunctionEnter3 *pFuncEnter3, /* [in] */ FunctionLeave3 *pFuncLeave3, - /* [in] */ FunctionTailcall3 *pFuncTailcall3){ - //ATLTRACE(_T("SetEnterLeaveFunctionHooks3")); + /* [in] */ FunctionTailcall3 *pFuncTailcall3) override + { + //ATLTRACE(_T("SetEnterLeaveFunctionHooks3\n")); return m_pProfilerInfo3->SetEnterLeaveFunctionHooks3(pFuncEnter3, pFuncLeave3, pFuncTailcall3); } virtual HRESULT STDMETHODCALLTYPE SetEnterLeaveFunctionHooks3WithInfo( /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo, /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo, - /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo){ - //ATLTRACE(_T("SetEnterLeaveFunctionHooks3WithInfo")); + /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo) override + { + //ATLTRACE(_T("SetEnterLeaveFunctionHooks3WithInfo\n")); return m_pProfilerInfo3->SetEnterLeaveFunctionHooks3WithInfo(pFuncEnter3WithInfo, pFuncLeave3WithInfo, pFuncTailcall3WithInfo); } @@ -513,8 +577,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, /* [out][in] */ ULONG *pcbArgumentInfo, - /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo){ - //ATLTRACE(_T("GetFunctionEnter3Info")); + /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo) override + { + //ATLTRACE(_T("GetFunctionEnter3Info\n")); return m_pProfilerInfo3->GetFunctionEnter3Info(functionId, eltInfo, pFrameInfo, pcbArgumentInfo, pArgumentInfo); } @@ -522,22 +587,25 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo, - /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange){ - //ATLTRACE(_T("GetFunctionLeave3Info")); + /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange) override + { + //ATLTRACE(_T("GetFunctionLeave3Info\n")); return m_pProfilerInfo3->GetFunctionLeave3Info(functionId, eltInfo, pFrameInfo, pRetvalRange); } virtual HRESULT STDMETHODCALLTYPE GetFunctionTailcall3Info( /* [in] */ FunctionID functionId, /* [in] */ COR_PRF_ELT_INFO eltInfo, - /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo){ - //ATLTRACE(_T("GetFunctionTailcall3Info")); + /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo) override + { + //ATLTRACE(_T("GetFunctionTailcall3Info\n")); return m_pProfilerInfo3->GetFunctionTailcall3Info(functionId, eltInfo, pFrameInfo); } virtual HRESULT STDMETHODCALLTYPE EnumModules( - /* [out] */ ICorProfilerModuleEnum **ppEnum){ - //ATLTRACE(_T("EnumModules")); + /* [out] */ ICorProfilerModuleEnum **ppEnum) override + { + //ATLTRACE(_T("EnumModules\n")); return m_pProfilerInfo3->EnumModules(ppEnum); } @@ -551,8 +619,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ULONG cchVersionString, /* [out] */ ULONG *pcchVersionString, /* [annotation][out] */ - _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[]){ - //ATLTRACE(_T("GetRuntimeInformation")); + _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[]) override + { + //ATLTRACE(_T("GetRuntimeInformation\n")); return m_pProfilerInfo3->GetRuntimeInformation(pClrInstanceId, pRuntimeType, pMajorVersion, pMinorVersion, pBuildNumber, pQFEVersion, cchVersionString, pcchVersionString, szVersionString); } @@ -562,8 +631,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ mdFieldDef fieldToken, /* [in] */ AppDomainID appDomainId, /* [in] */ ThreadID threadId, - /* [out] */ void **ppAddress){ - //ATLTRACE(_T("GetThreadStaticAddress2")); + /* [out] */ void **ppAddress) override + { + //ATLTRACE(_T("GetThreadStaticAddress2\n")); return m_pProfilerInfo3->GetThreadStaticAddress2(classId, fieldToken, appDomainId, threadId, ppAddress); } @@ -572,8 +642,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ModuleID moduleId, /* [in] */ ULONG32 cAppDomainIds, /* [out] */ ULONG32 *pcAppDomainIds, - /* [length_is][size_is][out] */ AppDomainID appDomainIds[]){ - //ATLTRACE(_T("GetAppDomainsContainingModule")); + /* [length_is][size_is][out] */ AppDomainID appDomainIds[]) override + { + //ATLTRACE(_T("GetAppDomainsContainingModule\n")); return m_pProfilerInfo3->GetAppDomainsContainingModule(moduleId, cAppDomainIds, pcAppDomainIds, appDomainIds); } @@ -586,29 +657,33 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [annotation][out] */ _Out_writes_to_(cchName, *pcchName) WCHAR szName[], /* [out] */ AssemblyID *pAssemblyId, - /* [out] */ DWORD *pdwModuleFlags){ - //ATLTRACE(_T("GetModuleInfo2")); + /* [out] */ DWORD *pdwModuleFlags) override + { + //ATLTRACE(_T("GetModuleInfo2\n")); return m_pProfilerInfo3->GetModuleInfo2(moduleId, ppBaseLoadAddress, cchName, pcchName, szName, pAssemblyId, pdwModuleFlags); } public: // ICorProfilerInfo4 virtual HRESULT STDMETHODCALLTYPE EnumThreads( - /* [out] */ ICorProfilerThreadEnum **ppEnum){ - //ATLTRACE(_T("EnumThreads")); + /* [out] */ ICorProfilerThreadEnum **ppEnum) override + { + //ATLTRACE(_T("EnumThreads\n")); return m_pProfilerInfo4->EnumThreads(ppEnum); } - virtual HRESULT STDMETHODCALLTYPE InitializeCurrentThread(void){ - //ATLTRACE(_T("InitializeCurrentThread")); + virtual HRESULT STDMETHODCALLTYPE InitializeCurrentThread(void) override + { + //ATLTRACE(_T("InitializeCurrentThread\n")); return m_pProfilerInfo4->InitializeCurrentThread(); } virtual HRESULT STDMETHODCALLTYPE RequestReJIT( /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[], - /* [size_is][in] */ mdMethodDef methodIds[]){ - //ATLTRACE(_T("RequestReJIT")); + /* [size_is][in] */ mdMethodDef methodIds[]) override + { + //ATLTRACE(_T("RequestReJIT\n")); return m_pProfilerInfo4->RequestReJIT(cFunctions, moduleIds, methodIds); } @@ -616,8 +691,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ULONG cFunctions, /* [size_is][in] */ ModuleID moduleIds[], /* [size_is][in] */ mdMethodDef methodIds[], - /* [size_is][out] */ HRESULT status[]){ - //ATLTRACE(_T("RequestRevert")); + /* [size_is][out] */ HRESULT status[]) override + { + //ATLTRACE(_T("RequestRevert\n")); return m_pProfilerInfo4->RequestRevert(cFunctions, moduleIds, methodIds, status); } @@ -626,16 +702,18 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cCodeInfos, /* [out] */ ULONG32 *pcCodeInfos, - /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[]){ - //ATLTRACE(_T("GetCodeInfo3")); + /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[]) override + { + //ATLTRACE(_T("GetCodeInfo3\n")); return m_pProfilerInfo4->GetCodeInfo3(functionID, reJitId, cCodeInfos, pcCodeInfos, codeInfos); } virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP2( /* [in] */ LPCBYTE ip, /* [out] */ FunctionID *pFunctionId, - /* [out] */ ReJITID *pReJitId){ - //ATLTRACE(_T("GetFunctionFromIP2")); + /* [out] */ ReJITID *pReJitId) override + { + //ATLTRACE(_T("GetFunctionFromIP2\n")); return m_pProfilerInfo4->GetFunctionFromIP2(ip, pFunctionId, pReJitId); } @@ -643,8 +721,9 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ FunctionID functionId, /* [in] */ ULONG cReJitIds, /* [out] */ ULONG *pcReJitIds, - /* [length_is][size_is][out] */ ReJITID reJitIds[]){ - //ATLTRACE(_T("GetClassFromObject")); + /* [length_is][size_is][out] */ ReJITID reJitIds[]) override + { + //ATLTRACE(_T("GetClassFromObject\n")); return m_pProfilerInfo4->GetReJITIDs(functionId, cReJitIds, pcReJitIds, reJitIds); } @@ -653,21 +732,24 @@ class CProfilerInfoBase : public ICorProfilerInfo4 /* [in] */ ReJITID reJitId, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, - /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[]){ - //ATLTRACE(_T("GetILToNativeMapping2")); + /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[]) override + { + //ATLTRACE(_T("GetILToNativeMapping2\n")); return m_pProfilerInfo4->GetILToNativeMapping2(functionId, reJitId, cMap, pcMap, map); } virtual HRESULT STDMETHODCALLTYPE EnumJITedFunctions2( - /* [out] */ ICorProfilerFunctionEnum **ppEnum){ - //ATLTRACE(_T("EnumJITedFunctions2")); + /* [out] */ ICorProfilerFunctionEnum **ppEnum) override + { + //ATLTRACE(_T("EnumJITedFunctions2\n")); return m_pProfilerInfo4->EnumJITedFunctions2(ppEnum); } virtual HRESULT STDMETHODCALLTYPE GetObjectSize2( /* [in] */ ObjectID objectId, - /* [out] */ SIZE_T *pcSize){ - //ATLTRACE(_T("GetObjectSize2")); + /* [out] */ SIZE_T *pcSize) override + { + //ATLTRACE(_T("GetObjectSize2\n")); return m_pProfilerInfo4->GetObjectSize2(objectId, pcSize); } diff --git a/main/OpenCover.Profiler/SharedMemory.cpp b/main/OpenCover.Profiler/SharedMemory.cpp index 8d8fe5189..07f792741 100644 --- a/main/OpenCover.Profiler/SharedMemory.cpp +++ b/main/OpenCover.Profiler/SharedMemory.cpp @@ -12,13 +12,13 @@ CSharedMemory::~CSharedMemory() { } void CSharedMemory::CloseMapping() { - if (m_hMemory != NULL) { - for (auto it = m_viewMap.begin(); it != m_viewMap.end(); it++) { + if (m_hMemory != nullptr) { + for (auto it = m_viewMap.begin(); it != m_viewMap.end(); ++it) { ::UnmapViewOfFile((*it).first); } m_viewMap.clear(); CloseHandle(m_hMemory); - m_hMemory = NULL; + m_hMemory = nullptr; } } @@ -29,7 +29,7 @@ void CSharedMemory::OpenFileMapping(const TCHAR* pName) { void* CSharedMemory::MapViewOfFile(DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) { if (!IsValid()) { - return NULL; + return nullptr; } void* pMappedData = ::MapViewOfFile( m_hMemory, @@ -39,14 +39,14 @@ void* CSharedMemory::MapViewOfFile(DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow dwNumberOfBytesToMap ); - if (pMappedData != NULL) { + if (pMappedData != nullptr) { m_viewMap.push_back(std::pair(pMappedData, dwNumberOfBytesToMap)); } return pMappedData; } void CSharedMemory::FlushViewOfFile() { - for (auto it = m_viewMap.begin(); it != m_viewMap.end(); it++) { + for (auto it = m_viewMap.begin(); it != m_viewMap.end(); ++it) { ::FlushViewOfFile((*it).first, (*it).second); } } diff --git a/main/OpenCover.Profiler/SharedMemory.h b/main/OpenCover.Profiler/SharedMemory.h index f4ff0a2f0..a91394d92 100644 --- a/main/OpenCover.Profiler/SharedMemory.h +++ b/main/OpenCover.Profiler/SharedMemory.h @@ -8,14 +8,14 @@ class CSharedMemory { public: - CSharedMemory() : m_hMemory(NULL) { } + CSharedMemory() : m_hMemory(nullptr) { } ~CSharedMemory(); public: void OpenFileMapping(const TCHAR *pName); void* MapViewOfFile(DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap); static DWORD GetAllocationGranularity(); - bool IsValid() {return m_hMemory!=NULL; } + bool IsValid() { return m_hMemory != nullptr; } void FlushViewOfFile(); private: diff --git a/main/OpenCover.Profiler/Synchronization.h b/main/OpenCover.Profiler/Synchronization.h index c2022712c..9ba7da82b 100644 --- a/main/OpenCover.Profiler/Synchronization.h +++ b/main/OpenCover.Profiler/Synchronization.h @@ -10,38 +10,38 @@ class CMutex { public: - CMutex() : m_hMutex(NULL) {} + CMutex() : m_hMutex(nullptr) {} ~CMutex() { CloseHandle(); } - bool IsValid() {return m_hMutex!=NULL; } + bool IsValid() { return m_hMutex != nullptr; } public: - void Initialise(const TCHAR * pName) { CloseHandle(); m_hMutex = ::CreateMutex(NULL, false, pName); } - void Enter(){ if (m_hMutex!=NULL) { ::WaitForSingleObject(m_hMutex, INFINITE);} } - void Leave(){ if (m_hMutex!=NULL) { ::ReleaseMutex(m_hMutex);} } + void Initialise(const TCHAR * pName) { CloseHandle(); m_hMutex = ::CreateMutex(nullptr, false, pName); } + void Enter(){ if (m_hMutex != nullptr) { ::WaitForSingleObject(m_hMutex, INFINITE); } } + void Leave(){ if (m_hMutex != nullptr) { ::ReleaseMutex(m_hMutex); } } private: HANDLE m_hMutex; - void CloseHandle() {if (m_hMutex!=NULL) { ::CloseHandle(m_hMutex); m_hMutex=NULL; }} + void CloseHandle() { if (m_hMutex != nullptr) { ::CloseHandle(m_hMutex); m_hMutex = nullptr; } } }; class CSemaphore { public: - CSemaphore() : m_hSemaphore(NULL) {} + CSemaphore() : m_hSemaphore(nullptr) {} ~CSemaphore() { CloseHandle(); } - bool IsValid() { return m_hSemaphore != NULL; } + bool IsValid() { return m_hSemaphore != nullptr; } public: - void Initialise(const TCHAR * pName) { CloseHandle(); m_hSemaphore = ::CreateSemaphore(NULL, 0, 2, pName); _handleName = pName; } + void Initialise(const TCHAR * pName) { CloseHandle(); m_hSemaphore = ::CreateSemaphore(nullptr, 0, 2, pName); _handleName = pName; } void Enter(){ if (IsValid()) { ::WaitForSingleObject(m_hSemaphore, INFINITE); } } - void Leave(){ if (IsValid()) { ::ReleaseSemaphore(m_hSemaphore, 1, NULL); } } + void Leave(){ if (IsValid()) { ::ReleaseSemaphore(m_hSemaphore, 1, nullptr); } } protected: HANDLE m_hSemaphore; tstring _handleName; private: - void CloseHandle() { if (IsValid()) { ::CloseHandle(m_hSemaphore); m_hSemaphore = NULL; } } + void CloseHandle() { if (IsValid()) { ::CloseHandle(m_hSemaphore); m_hSemaphore = nullptr; } } }; class CSemaphoreEx : public CSemaphore { @@ -51,12 +51,12 @@ class CSemaphoreEx : public CSemaphore { LONG prevCount = -1; if (::ReleaseSemaphore(m_hSemaphore, 1, &prevCount) && prevCount == 0){ // +1 if (::WaitForSingleObject(m_hSemaphore, 1000) == WAIT_TIMEOUT){ // -1 - RELTRACE(_T("Semaphore wait timed out => %s"), _handleName.c_str()); + RELTRACE(_T("Semaphore wait timed out => %s\n"), _handleName.c_str()); return -1; } } else { - RELTRACE(_T("Semaphore count failed => %s, %d"), _handleName.c_str(), prevCount); + RELTRACE(_T("Semaphore count failed => %s, %d\n"), _handleName.c_str(), prevCount); } return prevCount; } @@ -78,12 +78,12 @@ class CScopedLock class CEvent { public: - CEvent () : m_hEvent(NULL) { } + CEvent() : m_hEvent(nullptr) { } ~CEvent() { CloseHandle(); } - bool IsValid() {return m_hEvent!=NULL; } + bool IsValid() { return m_hEvent != nullptr; } public: - void Initialise(const TCHAR * pName, BOOL bManualReset = TRUE) { CloseHandle(); m_hEvent = ::CreateEvent(NULL, bManualReset, FALSE, pName); } + void Initialise(const TCHAR * pName, BOOL bManualReset = TRUE) { CloseHandle(); m_hEvent = ::CreateEvent(nullptr, bManualReset, FALSE, pName); } void Set() { ::SetEvent(m_hEvent); } void Wait() { ::WaitForSingleObject(m_hEvent, INFINITE); } @@ -92,6 +92,6 @@ class CEvent private: HANDLE m_hEvent; - void CloseHandle() {if (m_hEvent!= NULL) { ::CloseHandle(m_hEvent); m_hEvent = NULL; }} + void CloseHandle() { if (m_hEvent != nullptr) { ::CloseHandle(m_hEvent); m_hEvent = nullptr; } } }; diff --git a/main/OpenCover.Specs/Steps/PackagingSteps.cs b/main/OpenCover.Specs/Steps/PackagingSteps.cs index e4358ef93..fca733f1b 100644 --- a/main/OpenCover.Specs/Steps/PackagingSteps.cs +++ b/main/OpenCover.Specs/Steps/PackagingSteps.cs @@ -132,7 +132,7 @@ public void WhenIExecuteTheDeployedOpenCoverAgainstTheXTargetApplicationInSubfol var folder = (string)ScenarioContext.Current["targetFolder"]; var output = (string)ScenarioContext.Current["targetOutput"]; - var outputXml = string.Format(@"{0}\{1}_{2}.{3}", + var outputXml = string.Format(@"{0}\{1}_{2}{3}", Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), binFolder, Path.GetExtension(output)); if (File.Exists(outputXml)) File.Delete(outputXml); @@ -156,11 +156,11 @@ public void ThenTheCoverageResultsShouldBeTheSame() var output = (string)ScenarioContext.Current["targetOutput"]; - var outputXml86 = string.Format(@"{0}\{1}_{2}.{3}", + var outputXml86 = string.Format(@"{0}\{1}_{2}{3}", Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x86", Path.GetExtension(output)); - var outputXml64 = string.Format(@"{0}\{1}_{2}.{3}", - Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x86", Path.GetExtension(output)); + var outputXml64 = string.Format(@"{0}\{1}_{2}{3}", + Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x64", Path.GetExtension(output)); Assert.IsTrue(File.Exists(outputXml86)); Assert.IsTrue(File.Exists(outputXml64)); diff --git a/main/OpenCover.Test/Framework/CommandLineParserTests.cs b/main/OpenCover.Test/Framework/CommandLineParserTests.cs index 1f9deaf4a..bb0361fa1 100644 --- a/main/OpenCover.Test/Framework/CommandLineParserTests.cs +++ b/main/OpenCover.Test/Framework/CommandLineParserTests.cs @@ -719,6 +719,7 @@ public void HandlesServiceStartTimeout(string timeAsString, int expectedMinutes, Assert.That(parser.ServiceStartTimeout, Is.EqualTo(new TimeSpan(0, expectedMinutes, expectedSeconds))); } + [Test] [TestCase("10")] [TestCase("NaNs")] [TestCase("indifferenttext")] @@ -735,6 +736,41 @@ public void InvalidServiceStartTimeoutThrowsException(string invalidTimeout) Assert.That(thrownException.Message, Contains.Substring(invalidTimeout)); } + [Test] + [TestCase(10000, 10000)] + [TestCase(30000, 30000)] + [TestCase(60000, 60000)] + [TestCase(100, 10000)] + [TestCase(70000, 60000)] + public void HandlesCommunicationTimeout(int suppliedMillisconds, int expectedMiliseconds) + { + // arrange + var parser = new CommandLineParser(new[] { string.Format("-communicationtimeout:{0}", suppliedMillisconds), RequiredArgs }); + + // act + parser.ExtractAndValidateArguments(); + + // assert + Assert.That(parser.CommunicationTimeout, Is.EqualTo(expectedMiliseconds)); + + } + + [Test] + [TestCase("NaNs")] + [TestCase("indifferenttext")] + public void InvalidServiceCommunicationTimeoutThrowsException(string invalidTimeout) + { + // arrange + var parser = new CommandLineParser(new[] { "-communicationtimeout:" + invalidTimeout, RequiredArgs }); + + // act + var thrownException = Assert.Throws(parser.ExtractAndValidateArguments); + + // assert + Assert.That(thrownException.Message, Contains.Substring("communication timeout")); + Assert.That(thrownException.Message, Contains.Substring(invalidTimeout)); + } + [Test] [TestCase("-{nunit-console*}[*]* -{pdb*}[*]* -{nunit-agent*}[*]*")] [TestCase("-[System*]* -[Xyz*]* -[Zap*]*")] diff --git a/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs b/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs index 999053948..709ed20aa 100644 --- a/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs +++ b/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs @@ -77,6 +77,33 @@ public void Manager_Adds_Supplied_Threshold_EnvironmentVariable() Assert.NotNull(dict[@"OpenCover_Profiler_Threshold"]); Assert.AreEqual("500", dict[@"OpenCover_Profiler_Threshold"]); } + [Test] + public void Manager_DoesNotAdd_ShortWait_EnvironmentVariable() + { + // arrange + var dict = new StringDictionary(); + + // act + RunSimpleProcess(dict); + + // assert + Assert.Null(dict[@"OpenCover_Profiler_ShortWait"]); + } + + [Test] + public void Manager_Adds_Supplied_ShortWait_EnvironmentVariable() + { + // arrange + var dict = new StringDictionary(); + Container.GetMock().SetupGet(x => x.CommunicationTimeout).Returns(10000); + + // act + RunSimpleProcess(dict); + + // assert + Assert.NotNull(dict[@"OpenCover_Profiler_ShortWait"]); + Assert.AreEqual("10000", dict[@"OpenCover_Profiler_ShortWait"]); + } [Test] public void Manager_Adds_TraceByTest_EnvironmentVariable_When_Tracing_Enabled() @@ -146,8 +173,8 @@ public void Manager_DoesNotAdd_Cor_Profiler_Path_EnvironmentVariable_WithNormalR RunSimpleProcess(dict); // assert - Assert.IsFalse(dict.ContainsKey(@"Cor_Profiler_Path")); - Assert.IsFalse(dict.ContainsKey(@"CorClr_Profiler_Path")); + Assert.IsFalse(!(dict.ContainsKey(@"Cor_Profiler_Path") || !string.IsNullOrEmpty(dict[@"Cor_Profiler_Path"]))); + Assert.IsFalse(!(dict.ContainsKey(@"CorClr_Profiler_Path") || !string.IsNullOrEmpty(dict[@"CorClr_Profiler_Path"]))); } [Test] @@ -161,8 +188,8 @@ public void Manager_DoesNotAdd_Cor_Profiler_Path_EnvironmentVariable_WithUserReg RunSimpleProcess(dict); // assert - Assert.IsFalse(dict.ContainsKey(@"Cor_Profiler_Path")); - Assert.IsFalse(dict.ContainsKey(@"CorClr_Profiler_Path")); + Assert.IsFalse(!(dict.ContainsKey(@"Cor_Profiler_Path") || !string.IsNullOrEmpty(dict[@"Cor_Profiler_Path"]))); + Assert.IsFalse(!(dict.ContainsKey(@"CorClr_Profiler_Path") || !string.IsNullOrEmpty(dict[@"CorClr_Profiler_Path"]))); } [Test] diff --git a/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs b/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs index f53dcb00d..ebeaf9d0a 100644 --- a/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs +++ b/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs @@ -340,8 +340,8 @@ public void Commit_With_WithBranchPointsOnly() Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumSequencePoints); Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedSequencePoints); - Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumBranchPoints); - Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedBranchPoints); + Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumBranchPoints); + Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedBranchPoints); } [Test] diff --git a/main/OpenCover.Test/Integration/ThreadingTests.cs b/main/OpenCover.Test/Integration/ThreadingTests.cs new file mode 100644 index 000000000..af48c7148 --- /dev/null +++ b/main/OpenCover.Test/Integration/ThreadingTests.cs @@ -0,0 +1,58 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using NUnit.Framework; +using OpenCover.Framework; + +namespace OpenCover.Test.Integration +{ + /// + /// Replicates issue with threads as reported in issue #366 + /// + [TestFixture] + public class ThreadingTests + { + const int NB_THREADS = 50; + static readonly ManualResetEvent[] ResetEvents = new ManualResetEvent[NB_THREADS]; + + [Test] + public void RunManyThreads() + { + //Thread.Sleep(15000); + for (int i = 0; i < NB_THREADS; i++) + { + ResetEvents[i] = new ManualResetEvent(false); + new Thread(DoWork).Start(ResetEvents[i]); + } + var chrono = Stopwatch.StartNew(); + long n = 0; + while (n < 2000) + { + if (++n % 200 == 0) + Console.WriteLine(n.ToString()); + var current = WaitHandle.WaitAny(ResetEvents.ToArray()); + ResetEvents[current].Reset(); + new Thread(DoWork).Start(ResetEvents[current]); + } + Console.WriteLine("Took {0} seconds", chrono.Elapsed.TotalSeconds); + Assert.Pass(); + } + + public static void DoWork(object o) + { + var resetEvent = (ManualResetEvent)o; + resetEvent.Do(re => + { + var rnd = new Random(); + double res = 0; + for (var i = 0; i < 10000; i++) + res += rnd.NextDouble(); + re.Set(); + }); + + + } + + } +} diff --git a/main/OpenCover.Test/OpenCover.Test.csproj b/main/OpenCover.Test/OpenCover.Test.csproj index fb09b74b3..755e145ef 100644 --- a/main/OpenCover.Test/OpenCover.Test.csproj +++ b/main/OpenCover.Test/OpenCover.Test.csproj @@ -167,6 +167,7 @@ + diff --git a/main/OpenCover.UITest/LaunchSimpleTest.cs b/main/OpenCover.UITest/LaunchSimpleTest.cs index cc251a06f..cf168ec42 100644 --- a/main/OpenCover.UITest/LaunchSimpleTest.cs +++ b/main/OpenCover.UITest/LaunchSimpleTest.cs @@ -1,6 +1,6 @@ using System.Diagnostics; using System.IO; -using Microsoft.VisualStudio.TestTools.UITesting; +//using Microsoft.VisualStudio.TestTools.UITesting; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -9,7 +9,7 @@ namespace OpenCover.UITest /// /// Summary description for CodedUITest1 /// - [CodedUITest] + //[CodedUITest] public class LaunchSimpleTest { public LaunchSimpleTest() @@ -29,8 +29,8 @@ public void RunApp() pi.EnvironmentVariables["Stuff"] = "1"; pi.UseShellExecute = false; //pi.LoadUserProfile = true; - var application = ApplicationUnderTest.Launch(pi); - application.Process.WaitForExit(10000); + //var application = ApplicationUnderTest.Launch(pi); + //application.Process.WaitForExit(10000); } #region Additional test attributes diff --git a/main/cmdline/dogfood.cmd b/main/cmdline/dogfood.cmd index 7d00a3c70..d33e17758 100644 --- a/main/cmdline/dogfood.cmd +++ b/main/cmdline/dogfood.cmd @@ -1 +1,5 @@ -OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow /exclude:AdminOnly" -filter:"+[Open*]* -[OpenCover.T*]* -{nunit-console*}[*]* -{pdb*}[*]*" -output:opencovertests.xml +@echo off +pushd %cd% +cd %~dp0 +OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow /exclude:AdminOnly" -filter:"+[Open*]* -[OpenCover.T*]* -{nunit-console*}[*]* -{pdb*}[*]*" -output:opencovertests.xml -communicationtimeout:9999 +popd \ No newline at end of file diff --git a/tools/CrashReporterSigned/CrashReporter.NET.dll b/tools/CrashReporterSigned/CrashReporter.NET.dll new file mode 100644 index 000000000..f2d05ec7a Binary files /dev/null and b/tools/CrashReporterSigned/CrashReporter.NET.dll differ