static void TraceRunningProcess(int pid, TraceOutputOptions options) { var hProcess = WinProcesses.NativeMethods.OpenProcess(WinProcesses.ProcessAccessFlags.Synchronize, false, pid); if (hProcess.IsInvalid) { Console.Error.WriteLine("ERROR: the process with a given PID was not found or you don't have access to it."); return; } using (TraceCollector kernelTraceCollector = new KernelTraceCollector(pid, Console.Out, options), userTraceCollector = new UserTraceCollector(pid, Console.Out, options)) { SetConsoleCtrlCHook(kernelTraceCollector, userTraceCollector); ThreadPool.QueueUserWorkItem((o) => { WinHandles.NativeMethods.WaitForSingleObject(hProcess, VsChromium.Core.Win32.Constants.INFINITE); kernelTraceCollector.Stop(); userTraceCollector.Stop(); stopEvent.Set(); }); ThreadPool.QueueUserWorkItem((o) => { kernelTraceCollector.Start(); }); ThreadPool.QueueUserWorkItem((o) => { userTraceCollector.Start(); }); stopEvent.WaitOne(); } }
public UserTraceCollector(int pid, TextWriter output, TraceOutputOptions options) : base(CreateUserTraceEventSession(), output) { TraceEventParser parser = new MicrosoftWindowsRPCTraceEventParser(traceSession.Source); ITraceEventHandler eventHandler = new RpcTraceEventHandler(pid, output, options); eventHandler.SubscribeToEvents(parser); eventHandlers.Add(eventHandler); }
public KernelTraceCollector(int pid, TextWriter output, TraceOutputOptions options) : base(CreateKernelTraceEventSession(), output) { eventHandlers.Add(new SystemConfigTraceEventHandler(output, options)); eventHandlers.Add(new FileIOTraceEventHandler(pid, output, options)); eventHandlers.Add(new NetworkTraceEventHandler(pid, output, options)); eventHandlers.Add(new ProcessThreadsTraceEventHandler(pid, output, options)); eventHandlers.Add(new AlpcTraceEventHandler(pid, output, options)); foreach (var handler in eventHandlers) { handler.SubscribeToEvents(traceSession.Source.Kernel); } }
void WriteOptionalTraceInfo() { var traceInfo = new TraceEventCache(); #if !NET_3_5 if (TraceOutputOptions.HasFlag(TraceOptions.DateTime)) { PrintDateTime(traceInfo); } if (TraceOutputOptions.HasFlag(TraceOptions.ThreadId)) { PrintThreadId(traceInfo); } #endif }
private bool CallStackAdder(TraceEventType eventType) { if (TraceOutputOptions.HasFlag(TraceOptions.Callstack)) { return(false); } bool importantEvent = eventType.HasFlag(TraceEventType.Error) || eventType.HasFlag(TraceEventType.Critical); if (!importantEvent) { return(false); } TraceOutputOptions |= TraceOptions.Callstack; return(true); }
void WriteOptionalTraceInfo() { #if !__MOBILE__ var traceInfo = new TraceEventCache(); if (TraceOutputOptions.HasFlag(TraceOptions.ThreadId)) { PrintThreadId(traceInfo); } if (TraceOutputOptions.HasFlag(TraceOptions.DateTime)) { PrintDateTime(traceInfo); } if (TraceOutputOptions.HasFlag(TraceOptions.Timestamp)) { PrintTimeStamp(traceInfo); } #endif }
public override void TraceEvent(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, String message) { var builder = new StringBuilder(); if (TraceOutputOptions.HasFlag(TraceOptions.DateTime)) { builder.AppendFormat("[{0:HH':'mm':'ss.fff}] {1,-16}", DateTime.Now, eventType); } else { builder.AppendFormat("{0,-16}", eventType); } if (!message.IsNullOrWhiteSpace()) { builder.Append(message); } WriteLine(builder.ToString()); }
public ProcessThreadsTraceEventHandler(int pid, TextWriter output, TraceOutputOptions options) { summaryOutput = options == TraceOutputOptions.NoSummary ? TextWriter.Null : output; traceOutput = options == TraceOutputOptions.OnlySummary ? TextWriter.Null : output; this.pid = pid; }
protected string BuildJsonEventData( DateTime timestamp, string source, TraceEventType eventType, int id, object data, string callstack = null, Stack logicalOperationStack = null, int processId = 0, int threadId = 0) { var traceData = new JsonTraceData { Timestamp = timestamp, Source = source, Id = id, Type = eventType.ToString(), Host = Environment.MachineName, User = Environment.UserName, }; if (TraceOutputOptions != TraceOptions.None) { var traceOptions = Enum.GetValues(typeof(TraceOptions)).Cast <TraceOptions>(); foreach (var traceOption in traceOptions) { if (TraceOutputOptions.HasFlag(traceOption)) { switch (traceOption) { case TraceOptions.Callstack: traceData.Callstack = callstack; break; case TraceOptions.LogicalOperationStack: traceData.LogicalOperationStack = logicalOperationStack; break; case TraceOptions.ProcessId: traceData.ProcessId = processId > 0 ? processId : _processId; break; case TraceOptions.ThreadId: traceData.ThreadId = threadId > 0 ? threadId : System.Threading.Thread.CurrentThread.ManagedThreadId; break; case TraceOptions.DateTime: case TraceOptions.Timestamp: default: // NOP: not supported break; } } } } if (data != null) { traceData.Data = data; } traceData = ExtendOrReplaceJsonTraceData(traceData); var json = JsonConvert.SerializeObject(traceData, _serializerSettings); return(json); }
static void DoMain(string[] args) { if (TraceEventSession.IsElevated() != true) { Console.Error.WriteLine("Must be elevated (Admin) to run this program."); return; } List <string> procargs = null; bool showhelp = false, spawnNewConsoleWindow = false; TraceOutputOptions options = TraceOutputOptions.TracesAndSummary; int pid = 0; var p = new OptionSet { { "newconsole", "Start the process in a new console window.", v => { spawnNewConsoleWindow = v != null; } }, { "summary", "Prints only a summary of the collected trace.", v => { if (v != null) { options = TraceOutputOptions.OnlySummary; } } }, { "nosummary", "Prints only ETW events - no summary at the end.", v => { if (v != null) { options = TraceOutputOptions.NoSummary; } } }, { "h|help", "Show this message and exit", v => showhelp = v != null }, { "?", "Show this message and exit", v => showhelp = v != null } }; try { procargs = p.Parse(args); } catch (OptionException ex) { Console.Error.Write("ERROR: invalid argument"); Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(); showhelp = true; } catch (FormatException) { Console.Error.WriteLine("ERROR: invalid number in one of the constraints"); Console.Error.WriteLine(); showhelp = true; } Debug.Assert(procargs != null); if (!showhelp && procargs.Count == 0) { Console.Error.WriteLine("ERROR: please provide either process name or PID of the already running process"); Console.Error.WriteLine(); showhelp = true; } if (showhelp) { ShowHelp(p); return; } try { if (!int.TryParse(procargs[0], out pid)) { TraceNewProcess(procargs, spawnNewConsoleWindow, options); } else { TraceRunningProcess(pid, options); } } catch (COMException ex) { if ((uint)ex.HResult == 0x800700B7) { Console.Error.WriteLine("ERROR: could not start the kernel logger - make sure it is not running."); } } catch (Win32Exception ex) { Console.Error.WriteLine( $"ERROR: an error occurred while trying to start or open the process, hr: 0x{ex.HResult:X8}, " + $"code: 0x{ex.NativeErrorCode:X8} ({ex.Message})."); } catch (Exception ex) { Console.Error.WriteLine($"ERROR: severe error happened when starting application: {ex.Message}"); } }
static void TraceNewProcess(IEnumerable <string> procargs, bool spawnNewConsoleWindow, TraceOutputOptions options) { using (var process = new ProcessCreator(procargs) { SpawnNewConsoleWindow = spawnNewConsoleWindow }) { process.StartSuspended(); using (TraceCollector kernelTraceCollector = new KernelTraceCollector(process.ProcessId, Console.Out, options), userTraceCollector = new UserTraceCollector(process.ProcessId, Console.Out, options)) { SetConsoleCtrlCHook(kernelTraceCollector, userTraceCollector); ThreadPool.QueueUserWorkItem((o) => { kernelTraceCollector.Start(); }); ThreadPool.QueueUserWorkItem((o) => { userTraceCollector.Start(); }); ThreadPool.QueueUserWorkItem((o) => { process.Join(); kernelTraceCollector.Stop(); userTraceCollector.Stop(); stopEvent.Set(); }); Thread.Sleep(1000); // resume thread process.Resume(); stopEvent.WaitOne(); } } }
public SystemConfigTraceEventHandler(TextWriter output, TraceOutputOptions options) { this.output = options == TraceOutputOptions.NoSummary ? TextWriter.Null : output; }