Skip to content
This repository was archived by the owner on Nov 15, 2021. It is now read-only.

Commit d87319e

Browse files
committed
Merge pull request #386 from sawilde/master
a number of fixes
2 parents 9772367 + 54c551b commit d87319e

36 files changed

+730
-354
lines changed

ReleaseNotes.tmp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Version [[version]]
22
#376 protect buffer allocation in multithreaded environment (fix)
3+
#335 allow short wait timeout to be configured (feature)
34

45
Version 4.6.210 (rc - remove)
56
#282 exclude by process (feature)

main/OpenCover.Console/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static int Main(string[] args)
7474
{
7575
Logger.FatalFormat("An exception occured: {0}", ex.Message);
7676
Logger.FatalFormat("stack: {0}", ex.StackTrace);
77-
Logger.FatalFormat("A report has been sent to the OenCover development team...");
77+
Logger.FatalFormat("A report has been sent to the OpenCover development team...");
7878
}
7979

8080
ReportCrash(ex);
@@ -109,7 +109,7 @@ private static void ReportCrash(Exception exception)
109109

110110
uploader.SendAnonymousReport(SendRequestState.GetClientLib(), state.GetApplication(), state.GetExceptionDescription(true));
111111
}
112-
catch (Exception ex)
112+
catch (Exception)
113113
{
114114
System.Console.WriteLine("Failed to send crash report :(");
115115
}
@@ -303,7 +303,7 @@ private static void RunService(CommandLineParser parser, Action<StringDictionary
303303
// Stopping w3svc host
304304
if (parser.Target.ToLower().Equals("w3svc"))
305305
{
306-
logger.InfoFormat("Stopping svchost to clean up environment variables for w3svc", parser.Target);
306+
logger.InfoFormat("Stopping svchost to clean up environment variables for {0}", parser.Target);
307307
if (ServiceEnvironmentManagementEx.IsServiceStartAutomatic(parser.Target))
308308
{
309309
logger.InfoFormat("Please note that the 'w3svc' service may automatically start");

main/OpenCover.Framework/Bootstrapper.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ public void Initialise(IFilter filter,
7575
_container = builder.Build();
7676
}
7777

78+
/// <summary>
79+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
80+
/// </summary>
81+
/// <filterpriority>2</filterpriority>
7882
public void Dispose()
7983
{
8084
if (_container == null) return;

main/OpenCover.Framework/CommandLineParser.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ public string Usage()
113113
builder.AppendLine(" [-hideskipped:File|Filter|Attribute|MissingPdb|All,[File|Filter|Attribute|MissingPdb|All]]");
114114
builder.AppendLine(" [-log:[Off|Fatal|Error|Warn|Info|Debug|Verbose|All]]");
115115
builder.AppendLine(" [-service[:byname]]");
116-
builder.AppendLine(" [-servicestarttimeout:1m23s");
116+
builder.AppendLine(" [-servicestarttimeout:<minutes+seconds e.g. 1m23s>");
117+
builder.AppendLine(" [-communicationtimeout:<integer, e.g. 10000>");
117118
builder.AppendLine(" [-threshold:<max count>]");
118119
builder.AppendLine(" [-enableperformancecounters]");
119120
builder.AppendLine(" [-skipautoprops]");
@@ -190,6 +191,11 @@ public void ExtractAndValidateArguments()
190191
ReturnCodeOffset = ExtractValue<int>("returntargetcode", () =>
191192
{ throw new InvalidOperationException("The return target code offset must be an integer"); });
192193
break;
194+
case "communicationtimeout":
195+
CommunicationTimeout = ExtractValue<int>("communicationtimeout", () =>
196+
{ throw new InvalidOperationException(string.Format("The communication timeout must be an integer: {0}", GetArgumentValue("communicationtimeout"))); });
197+
CommunicationTimeout = Math.Max(Math.Min(CommunicationTimeout, 60000), 10000);
198+
break;
193199
case "filter":
194200
Filters = ExtractFilters(GetArgumentValue("filter"));
195201
break;
@@ -511,6 +517,11 @@ private void ValidateArguments()
511517
/// Instructs the console to print its version and exit
512518
/// </summary>
513519
public bool PrintVersion { get; private set; }
520+
521+
/// <summary>
522+
/// Sets the 'short' timeout between profiler and host (normally 10000ms)
523+
/// </summary>
524+
public int CommunicationTimeout { get; private set; }
514525
}
515526

516527
}

main/OpenCover.Framework/Communication/CommunicationManager.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using System;
2-
using System.Diagnostics;
32
using System.IO;
43
using System.Threading;
5-
using log4net.Repository.Hierarchy;
64
using OpenCover.Framework.Manager;
7-
using OpenCover.Framework.Service;
85

96
namespace OpenCover.Framework.Communication
107
{
@@ -48,6 +45,11 @@ public CommunicationManager(IMessageHandler messageHandler)
4845
_messageHandler = messageHandler;
4946
}
5047

48+
/// <summary>
49+
/// Process a communication related message from a profiler
50+
/// </summary>
51+
/// <param name="mcb"></param>
52+
/// <param name="offloadHandling"></param>
5153
public void HandleCommunicationBlock(IManagedCommunicationBlock mcb, Action<ManagedBufferBlock> offloadHandling)
5254
{
5355
mcb.ProfilerRequestsInformation.Reset();
@@ -71,6 +73,10 @@ private static void SendChunkAndWaitForConfirmation(int writeSize, IManagedCommu
7173
mcb.InformationReadByProfiler.Reset();
7274
}
7375

76+
/// <summary>
77+
/// process a results block from the profiler
78+
/// </summary>
79+
/// <param name="mmb"></param>
7480
public byte[] HandleMemoryBlock(IManagedMemoryBlock mmb)
7581
{
7682
mmb.ProfilerHasResults.Reset();
@@ -88,6 +94,9 @@ public byte[] HandleMemoryBlock(IManagedMemoryBlock mmb)
8894
return newData;
8995
}
9096

97+
/// <summary>
98+
/// Communication is over
99+
/// </summary>
91100
public void Complete()
92101
{
93102
_messageHandler.Complete();

main/OpenCover.Framework/Communication/MarshalWapper.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,24 @@ public interface IMarshalWrapper
3939
/// </summary>
4040
public class MarshalWrapper : IMarshalWrapper
4141
{
42+
/// <summary>
43+
/// Map pinned memory to a structure
44+
/// </summary>
45+
/// <typeparam name="T">The type of the structure</typeparam>
46+
/// <param name="pinnedMemory"></param>
47+
/// <returns></returns>
4248
public T PtrToStructure<T>(IntPtr pinnedMemory)
4349
{
4450
return (T)Marshal.PtrToStructure(pinnedMemory, typeof(T));
4551
}
4652

53+
/// <summary>
54+
/// Map a structure to pinned memory
55+
/// </summary>
56+
/// <typeparam name="T"></typeparam>
57+
/// <param name="structure"></param>
58+
/// <param name="pinnedMemory"></param>
59+
/// <param name="fDeleteOld"></param>
4760
public void StructureToPtr<T>(T structure, IntPtr pinnedMemory, bool fDeleteOld)
4861
{
4962
Marshal.StructureToPtr(structure, pinnedMemory, fDeleteOld);

main/OpenCover.Framework/Communication/MessageHandler.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ public MessageHandler(IProfilerCommunication profilerCommunication, IMarshalWrap
6767
_memoryManager = memoryManager;
6868
}
6969

70+
/// <summary>
71+
/// Process a Standard Message
72+
/// </summary>
73+
/// <param name="msgType"></param>
74+
/// <param name="mcb"></param>
75+
/// <param name="chunkReady"></param>
76+
/// <param name="offloadHandling"></param>
77+
/// <returns></returns>
7078
public int StandardMessage(MSG_Type msgType, IManagedCommunicationBlock mcb, Action<int, IManagedCommunicationBlock> chunkReady, Action<ManagedBufferBlock> offloadHandling)
7179
{
7280
IntPtr pinnedMemory = mcb.PinnedDataCommunication.AddrOfPinnedObject();
@@ -319,6 +327,9 @@ private int HandleTrackProcessMessage(IntPtr pinnedMemory)
319327

320328
private int _readSize;
321329

330+
/// <summary>
331+
/// Maximum size of a base message
332+
/// </summary>
322333
public int ReadSize
323334
{
324335
get
@@ -344,6 +355,9 @@ public int ReadSize
344355
}
345356
}
346357

358+
/// <summary>
359+
/// Finished
360+
/// </summary>
347361
public void Complete()
348362
{
349363
_profilerCommunication.Stopping();

main/OpenCover.Framework/Communication/Messages.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace OpenCover.Framework.Communication
1010
/// <summary>
1111
/// The command supportd by the host
1212
/// </summary>
13-
// ReSharper disable InconsistentNaming
13+
// ReSharper disable InconsistentNaming
14+
// ReSharper disable once EnumUnderlyingTypeIsInt
1415
public enum MSG_Type : int
1516
{
1617
/// <summary>
@@ -338,8 +339,15 @@ public struct MSG_AllocateBuffer_Request
338339
[StructLayout(LayoutKind.Sequential, Pack = 1)]
339340
public struct MSG_AllocateBuffer_Response
340341
{
342+
/// <summary>
343+
/// is the buffer allocated
344+
/// </summary>
341345
[MarshalAs(UnmanagedType.Bool)]
342346
public bool allocated;
347+
348+
/// <summary>
349+
/// The id assigned to the buffer
350+
/// </summary>
343351
public uint bufferId;
344352
}
345353

main/OpenCover.Framework/Filter.cs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
//
66
using System;
77
using System.Collections.Generic;
8-
using System.Diagnostics;
98
using System.IO;
109
using System.Linq;
1110
using System.Runtime.CompilerServices;
@@ -25,6 +24,10 @@ public class Filter : IFilter
2524
internal IList<RegexFilter> ExcludedAttributes { get; private set; }
2625
internal IList<RegexFilter> ExcludedFiles { get; private set; }
2726
internal IList<RegexFilter> TestFiles { get; private set; }
27+
28+
/// <summary>
29+
/// Are the filters supplied as reguar expressions
30+
/// </summary>
2831
public bool RegExFilters { get; private set; }
2932

3033

@@ -42,6 +45,13 @@ public Filter(bool useRegexFilters = false)
4245
RegExFilters = useRegexFilters;
4346
}
4447

48+
/// <summary>
49+
/// Decides whether an assembly should be included in the instrumentation
50+
/// </summary>
51+
/// <param name="processName">The name of the process being profiled</param>
52+
/// <param name="assemblyName">the name of the assembly under profile</param>
53+
/// <remarks>All assemblies matching either the inclusion or exclusion filter should be included
54+
/// as it is the class that is being filtered within these unless the class filter is *</remarks>
4555
public bool UseAssembly(string processName, string assemblyName)
4656
{
4757
processName = Path.GetFileNameWithoutExtension(processName);
@@ -65,6 +75,13 @@ public bool UseAssembly(string processName, string assemblyName)
6575
return false;
6676
}
6777

78+
/// <summary>
79+
/// Determine if an [assemblyname]classname pair matches the current Exclusion or Inclusion filters
80+
/// </summary>
81+
/// <param name="processName">The name of the process</param>
82+
/// <param name="assemblyName">the name of the assembly under profile</param>
83+
/// <param name="className">the name of the class under profile</param>
84+
/// <returns>false - if pair matches the exclusion filter or matches no filters, true - if pair matches in the inclusion filter</returns>
6885
public bool InstrumentClass(string processName, string assemblyName, string className)
6986
{
7087
if (string.IsNullOrEmpty(processName) || string.IsNullOrEmpty(assemblyName) || string.IsNullOrEmpty(className))
@@ -96,11 +113,23 @@ public bool InstrumentClass(string processName, string assemblyName, string clas
96113
}
97114

98115

116+
/// <summary>
117+
/// Determine if an [assemblyname]classname pair matches the current Exclusion or Inclusion filters
118+
/// </summary>
119+
/// <param name="assemblyName">the name of the assembly under profile</param>
120+
/// <param name="className">the name of the class under profile</param>
121+
/// <returns>false - if pair matches the exclusion filter or matches no filters, true - if pair matches in the inclusion filter</returns>
99122
public bool InstrumentClass(string assemblyName, string className)
100123
{
101124
return InstrumentClass(Guid.NewGuid().ToString(), assemblyName, className);
102125
}
103126

127+
/// <summary>
128+
/// Add a filter
129+
/// </summary>
130+
/// <param name="assemblyClassName">A filter is of the format (+ or -)[assemblyName]className, wildcards are allowed. <br/>
131+
/// i.e. -[mscorlib], -[System.*]*, +[App.*]*, +[*]*
132+
/// </param>
104133
public void AddFilter(string assemblyClassName)
105134
{
106135
string assemblyName;
@@ -154,11 +183,20 @@ private static InvalidOperationException InvalidFilterFormatException(string ass
154183
return new InvalidOperationException(string.Format("The supplied filter '{0}' does not meet the required format for a filter +-[assemblyname]classname", assemblyClassName));
155184
}
156185

186+
/// <summary>
187+
/// Add attribute exclusion filters
188+
/// </summary>
189+
/// <param name="exclusionFilters">An array of filters that are used to wildcard match an attribute</param>
157190
public void AddAttributeExclusionFilters(string[] exclusionFilters)
158191
{
159192
ExcludedAttributes.AddFilters(exclusionFilters, RegExFilters);
160193
}
161194

195+
/// <summary>
196+
/// Is this entity (method/type) excluded due to an attributeFilter
197+
/// </summary>
198+
/// <param name="entity">The entity to test</param>
199+
/// <returns></returns>
162200
public bool ExcludeByAttribute(IMemberDefinition entity)
163201
{
164202
if (ExcludedAttributes.Count == 0)
@@ -207,6 +245,11 @@ where excludeAttribute.IsMatchingExpression(customAttribute.AttributeType.FullNa
207245
select excludeAttribute).Any();
208246
}
209247

248+
/// <summary>
249+
/// Is this entity excluded due to an attributeFilter
250+
/// </summary>
251+
/// <param name="entity">The entity to test</param>
252+
/// <returns></returns>
210253
public bool ExcludeByAttribute(AssemblyDefinition entity)
211254
{
212255
if (ExcludedAttributes.Count == 0)
@@ -215,6 +258,11 @@ public bool ExcludeByAttribute(AssemblyDefinition entity)
215258
return ExcludeByAttribute((ICustomAttributeProvider)entity);
216259
}
217260

261+
/// <summary>
262+
/// Is this file excluded
263+
/// </summary>
264+
/// <param name="fileName">The name of the file to test</param>
265+
/// <returns></returns>
218266
public bool ExcludeByFile(string fileName)
219267
{
220268
if (ExcludedFiles.Count == 0 || string.IsNullOrWhiteSpace(fileName))
@@ -223,11 +271,20 @@ public bool ExcludeByFile(string fileName)
223271
return ExcludedFiles.Any(excludeFile => excludeFile.IsMatchingExpression(fileName));
224272
}
225273

274+
/// <summary>
275+
/// Add file exclusion filters
276+
/// </summary>
277+
/// <param name="exclusionFilters"></param>
226278
public void AddFileExclusionFilters(string[] exclusionFilters)
227279
{
228280
ExcludedFiles.AddFilters(exclusionFilters, RegExFilters);
229281
}
230282

283+
/// <summary>
284+
/// Decides whether an assembly should be analysed for test methods
285+
/// </summary>
286+
/// <param name="assemblyName">the name of the assembly under profile</param>
287+
/// <returns>true - if the assembly matches the test assembly filter</returns>
231288
public bool UseTestAssembly(string assemblyName)
232289
{
233290
if (TestFiles.Count == 0 || string.IsNullOrWhiteSpace(assemblyName))
@@ -236,11 +293,20 @@ public bool UseTestAssembly(string assemblyName)
236293
return TestFiles.Any(file => file.IsMatchingExpression(assemblyName));
237294
}
238295

296+
/// <summary>
297+
/// Add test file filters
298+
/// </summary>
299+
/// <param name="testFilters"></param>
239300
public void AddTestFileFilters(string[] testFilters)
240301
{
241302
TestFiles.AddFilters(testFilters, RegExFilters);
242303
}
243304

305+
/// <summary>
306+
/// Is the method an auto-implemented property get/set
307+
/// </summary>
308+
/// <param name="method"></param>
309+
/// <returns></returns>
244310
public bool IsAutoImplementedProperty(MethodDefinition method)
245311
{
246312
if ((method.IsSetter || method.IsGetter) && method.HasCustomAttributes)
@@ -250,6 +316,11 @@ public bool IsAutoImplementedProperty(MethodDefinition method)
250316
return false;
251317
}
252318

319+
/// <summary>
320+
/// Should we instrument this asssembly
321+
/// </summary>
322+
/// <param name="processName"></param>
323+
/// <returns></returns>
253324
public bool InstrumentProcess(string processName)
254325
{
255326
if (string.IsNullOrEmpty(processName))

main/OpenCover.Framework/ICommandLine.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,10 @@ public interface ICommandLine
5353
/// Should auto implemented properties be skipped
5454
/// </summary>
5555
bool SkipAutoImplementedProperties { get; }
56+
57+
/// <summary>
58+
/// Sets the 'short' timeout between profiler and host
59+
/// </summary>
60+
int CommunicationTimeout { get; }
5661
}
5762
}

0 commit comments

Comments
 (0)