/// <summary> /// Creates a new profiler using a process start info of an executable and a data writer. /// </summary> public Profiler(ProcessStartInfo info, IProfilingDataWriter dataWriter, ProfilerOptions options) { if (dataWriter == null) { throw new ArgumentNullException("dataWriter"); } if (info == null) { throw new ArgumentNullException("info"); } if (!DetectBinaryType.IsDotNetExecutable(info.FileName)) { throw new ProfilerException("File is not a valid .NET executable file!"); } this.profilerOptions = options; this.is64Bit = DetectBinaryType.RunsAs64Bit(info.FileName); this.profilerOutput = new StringBuilder(); this.performanceCounters = options.Counters; foreach (var counter in performanceCounters) { counter.Reset(); } this.dataWriter = dataWriter; this.threadListMutex = new Mutex(false, MutexId); this.accessEventHandle = new EventWaitHandle(true, EventResetMode.ManualReset, this.AccessEventId); this.psi = info; this.psi.UseShellExecute = false; // needed to get env vars working! this.psi.EnvironmentVariables["SharedMemoryName"] = SharedMemoryId; this.psi.EnvironmentVariables["MutexName"] = MutexId; // mutex for process pause/continue sychronization this.psi.EnvironmentVariables["AccessEventName"] = AccessEventId; // name for access event of controller this.psi.EnvironmentVariables["COR_ENABLE_PROFILING"] = "1"; // enable profiling; 0 = disable this.psi.EnvironmentVariables["COR_PROFILER"] = ProfilerGuid; // GUID for the profiler this.psi.EnvironmentVariables["COMPLUS_ProfAPI_ProfilerCompatibilitySetting"] = "EnableV2Profiler"; // enable CLR 2.0 for CLR 4.0 file = MemoryMappedFile.CreateSharedMemory(SharedMemoryId, profilerOptions.SharedMemorySize); fullView = file.MapView(0, profilerOptions.SharedMemorySize); this.dataWriter.ProcessorFrequency = GetProcessorFrequency(); this.logger = new Thread(new ParameterizedThreadStart(Logging)); this.logger.Name = "Logger"; this.logger.IsBackground = true; // don't let the logger thread prevent our process from exiting this.dataCollector = new Thread(new ThreadStart(DataCollection)); this.dataCollector.Name = "DataCollector"; this.dataCollector.IsBackground = true; }
/// <summary> /// Creates a new profiler using the path to an executable to profile and a data writer. /// </summary> public Profiler(string pathToExecutable, IProfilingDataWriter dataWriter, ProfilerOptions options) : this(new ProcessStartInfo(pathToExecutable), dataWriter, options) { if (!File.Exists(pathToExecutable)) { throw new FileNotFoundException("File not found!", pathToExecutable); } this.psi.WorkingDirectory = Path.GetDirectoryName(pathToExecutable); }
public ProfilerProcessRunner(IProfilingDataWriter writer, ProfilerOptions options) { if (writer == null) throw new ArgumentNullException("writer"); if (options == null) throw new ArgumentNullException("options"); this.writer = writer; this.options = options; this.psi = new ProcessStartInfo(); wasStarted = false; }
/// <summary> /// Creates a new profiler using a process start info of an executable and a data writer. /// </summary> public Profiler(ProcessStartInfo info, IProfilingDataWriter dataWriter, ProfilerOptions options) { if (dataWriter == null) throw new ArgumentNullException("dataWriter"); if (info == null) throw new ArgumentNullException("info"); if (!DetectBinaryType.IsDotNetExecutable(info.FileName)) throw new ProfilerException("File is not a valid .NET executable file!"); this.profilerOptions = options; this.is64Bit = DetectBinaryType.RunsAs64Bit(info.FileName); this.profilerOutput = new StringBuilder(); this.performanceCounters = options.Counters; foreach (var counter in performanceCounters) counter.Reset(); this.dataWriter = dataWriter; this.threadListMutex = new Mutex(false, MutexId); this.accessEventHandle = new EventWaitHandle(true, EventResetMode.ManualReset, this.AccessEventId); this.psi = info; this.psi.UseShellExecute = false; // needed to get env vars working! this.psi.EnvironmentVariables["SharedMemoryName"] = SharedMemoryId; this.psi.EnvironmentVariables["MutexName"] = MutexId; // mutex for process pause/continue sychronization this.psi.EnvironmentVariables["AccessEventName"] = AccessEventId; // name for access event of controller this.psi.EnvironmentVariables["COR_ENABLE_PROFILING"] = "1"; // enable profiling; 0 = disable this.psi.EnvironmentVariables["COR_PROFILER"] = ProfilerGuid; // GUID for the profiler this.psi.EnvironmentVariables["COMPLUS_ProfAPI_ProfilerCompatibilitySetting"] = "EnableV2Profiler"; // enable CLR 2.0 for CLR 4.0 file = MemoryMappedFile.CreateSharedMemory(SharedMemoryId, profilerOptions.SharedMemorySize); fullView = file.MapView(0, profilerOptions.SharedMemorySize); this.dataWriter.ProcessorFrequency = GetProcessorFrequency(); this.logger = new Thread(new ParameterizedThreadStart(Logging)); this.logger.Name = "Logger"; this.logger.IsBackground = true; // don't let the logger thread prevent our process from exiting this.dataCollector = new Thread(new ThreadStart(DataCollection)); this.dataCollector.Name = "DataCollector"; this.dataCollector.IsBackground = true; }
/// <summary> /// Creates a new profiler using the path to an executable to profile and a data writer. /// </summary> public Profiler(string pathToExecutable, IProfilingDataWriter dataWriter, ProfilerOptions options) : this(new ProcessStartInfo(pathToExecutable), dataWriter, options) { if (!File.Exists(pathToExecutable)) throw new FileNotFoundException("File not found!", pathToExecutable); this.psi.WorkingDirectory = Path.GetDirectoryName(pathToExecutable); }