internal unsafe bool SymRegisterCallbackProcInfo( IntPtr hProcess, TraceEventNativeMethods.SymCallbackActions ActionCode, ulong UserData, ulong UserContext) { //Console.WriteLine(ActionCode); switch (ActionCode) { // Symbol load has started, to cancel, return true case TraceEventNativeMethods.SymCallbackActions.CBA_DEFERRED_SYMBOL_LOAD_CANCEL: return false; case TraceEventNativeMethods.SymCallbackActions.CBA_DEFERRED_SYMBOL_LOAD_START: TraceEventNativeMethods.IMAGEHLP_DEFERRED_SYMBOL_LOAD64* pstartLoadEvent = (TraceEventNativeMethods.IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)UserData; Console.WriteLine("loading symbols for file " + new string((char*)pstartLoadEvent->FileName) + " started ...."); return true; case TraceEventNativeMethods.SymCallbackActions.CBA_DEFERRED_SYMBOL_LOAD_COMPLETE: TraceEventNativeMethods.IMAGEHLP_DEFERRED_SYMBOL_LOAD64* pLoadEvent = (TraceEventNativeMethods.IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)UserData; switch (pLoadEvent->Flags) { case TraceEventNativeMethods.DSLFLAG_MISMATCHED_DBG: Console.WriteLine("Mismatched DBG info"); break; case TraceEventNativeMethods.DSLFLAG_MISMATCHED_PDB: Console.WriteLine("Mismatched PDP"); break; default: Console.WriteLine("loading symbols for file " + new string((char*)pLoadEvent->FileName) + " Completed successfully"); break; } break; case TraceEventNativeMethods.SymCallbackActions.CBA_READ_MEMORY: Console.WriteLine("Requesting Read memory operation?!! what should i do"); break; case TraceEventNativeMethods.SymCallbackActions.CBA_DEBUG_INFO: char* pChar = (char*)UserData; Console.WriteLine(new string(pChar)); break; case TraceEventNativeMethods.SymCallbackActions.CBA_EVENT: TraceEventNativeMethods.IMAGEHLP_CBA_EVENT* pEvent = (TraceEventNativeMethods.IMAGEHLP_CBA_EVENT*)UserData; Console.WriteLine(new string(pEvent->pStrDesc)); return true; default: return false; // if we don't know how to handle this, we should return false. } return false; }
internal unsafe bool SymEnumSymbolsProc( TraceEventNativeMethods.SYMBOL_INFO* pSymInfo, uint SymbolSize, IntPtr UserContext) { char* p = (char*)&pSymInfo->Name; string s = new string(p); // Console.WriteLine(s); return true; }
private void RawDispatchClassic(TraceEventNativeMethods.EVENT_RECORD* eventData) { // TODO not really a EVENT_RECORD on input, but it is a pain to be type-correct. TraceEventNativeMethods.EVENT_TRACE* oldStyleHeader = (TraceEventNativeMethods.EVENT_TRACE*) eventData; eventData = convertedHeader; eventData->EventHeader.Size = (ushort) sizeof(TraceEventNativeMethods.EVENT_TRACE_HEADER); // HeaderType eventData->EventHeader.Flags = TraceEventNativeMethods.EVENT_HEADER_FLAG_CLASSIC_HEADER; // TODO Figure out if there is a marker that is used in the WOW for the classic providers // right now I assume they are all the same as the machine. if (pointerSize == 8) eventData->EventHeader.Flags |= TraceEventNativeMethods.EVENT_HEADER_FLAG_64_BIT_HEADER; else eventData->EventHeader.Flags |= TraceEventNativeMethods.EVENT_HEADER_FLAG_32_BIT_HEADER; // EventProperty eventData->EventHeader.ThreadId = oldStyleHeader->Header.ThreadId; eventData->EventHeader.ProcessId = oldStyleHeader->Header.ProcessId; eventData->EventHeader.TimeStamp = oldStyleHeader->Header.TimeStamp; eventData->EventHeader.ProviderId = oldStyleHeader->Header.Guid; // ProviderId = TaskId // ID left 0 eventData->EventHeader.Version = (byte) oldStyleHeader->Header.Version; // Channel eventData->EventHeader.Level = oldStyleHeader->Header.Level; eventData->EventHeader.Opcode = oldStyleHeader->Header.Type; // Task // Keyword eventData->EventHeader.KernelTime = oldStyleHeader->Header.KernelTime; eventData->EventHeader.UserTime = oldStyleHeader->Header.UserTime; // ActivityID eventData->BufferContext = oldStyleHeader->BufferContext; // ExtendedDataCount eventData->UserDataLength = (ushort) oldStyleHeader->MofLength; // ExtendedData eventData->UserData = oldStyleHeader->MofData; // UserContext RawDispatch(eventData); }
private void RawDispatch(TraceEventNativeMethods.EVENT_RECORD* rawData) { Debug.Assert(rawData->EventHeader.HeaderType == 0); // if non-zero probably old-style ETW header TraceEvent anEvent = Lookup(rawData); // Keep in mind that for UnhandledTraceEvent 'PrepForCallback' has NOT been called, which means the // opcode, guid and eventIds are not correct at this point. The ToString() routine WILL call // this so if that is in your debug window, it will have this side effect (which is good and bad) // Looking at rawData will give you the truth however. anEvent.DebugValidate(); if (anEvent.FixupETLData != null) anEvent.FixupETLData(); Dispatch(anEvent); }
private IntPtr ToUnmanagedBuffer(TraceEventNativeMethods.EVENT_TRACE_PROPERTIES properties, string fileName) { if (fileName == null) properties.LogFileNameOffset = 0; else properties.LogFileNameOffset = properties.LoggerNameOffset + MaxNameSize * 2; Marshal.StructureToPtr(properties, unmanagedPropertiesBuffer, false); byte[] buffer = Encoding.Unicode.GetBytes(sessionName); Marshal.Copy(buffer, 0, (IntPtr)(unmanagedPropertiesBuffer.ToInt64() + properties.LoggerNameOffset), buffer.Length); Marshal.WriteInt16(unmanagedPropertiesBuffer, (int)properties.LoggerNameOffset + buffer.Length, 0); if (fileName != null) { buffer = Encoding.Unicode.GetBytes(fileName); Marshal.Copy(buffer, 0, (IntPtr)(unmanagedPropertiesBuffer.ToInt64() + properties.LogFileNameOffset), buffer.Length); Marshal.WriteInt16(unmanagedPropertiesBuffer, (int)properties.LogFileNameOffset + buffer.Length, 0); } return unmanagedPropertiesBuffer; }
/// <summary> /// Given a mask of kernel flags, set the array stackTracingIds of size stackTracingIdsMax to match. /// It returns the number of entries in stackTracingIds that were filled in. /// </summary> private unsafe int SetStackTraceIds(KernelTraceEventParser.Keywords stackCapture, TraceEventNativeMethods.STACK_TRACING_EVENT_ID* stackTracingIds, int stackTracingIdsMax) { int curID = 0; // PerfInfo (sample profiling) if ((stackCapture & KernelTraceEventParser.Keywords.Profile) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.PerfInfoTaskGuid; stackTracingIds[curID].Type = 0x2e; // Sample Profile curID++; } if ((stackCapture & KernelTraceEventParser.Keywords.SystemCall) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.PerfInfoTaskGuid; stackTracingIds[curID].Type = 0x33; // SysCall curID++; } // TODO SysCall? // Thread if ((stackCapture & KernelTraceEventParser.Keywords.Thread) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.ThreadTaskGuid; stackTracingIds[curID].Type = 0x01; // Thread Create curID++; } if ((stackCapture & KernelTraceEventParser.Keywords.ContextSwitch) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.ThreadTaskGuid; if ((stackCapture & KernelTraceEventParser.Keywords.Thread) != 0) stackTracingIds[curID].Type = 0x24; // Context Switch curID++; } if ((stackCapture & KernelTraceEventParser.Keywords.Dispatcher) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.ThreadTaskGuid; stackTracingIds[curID].Type = 0x32; // Ready Thread curID++; } // Image if ((stackCapture & KernelTraceEventParser.Keywords.ImageLoad) != 0) { // Confirm this is not ImageTaskGuid stackTracingIds[curID].EventGuid = KernelTraceEventParser.ProcessTaskGuid; stackTracingIds[curID].Type = 0x0A; // Image Load curID++; } // Process if ((stackCapture & KernelTraceEventParser.Keywords.Process) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.ProcessTaskGuid; stackTracingIds[curID].Type = 0x01; // Process Create curID++; } // Disk if ((stackCapture & KernelTraceEventParser.Keywords.DiskIOInit) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.DiskIoTaskGuid; stackTracingIds[curID].Type = 0x0c; // Read Init curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.DiskIoTaskGuid; stackTracingIds[curID].Type = 0x0d; // Write Init curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.DiskIoTaskGuid; stackTracingIds[curID].Type = 0x0f; // Flush Init curID++; } // Virtual Alloc if ((stackCapture & KernelTraceEventParser.Keywords.VirtualAlloc) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.VirtualAllocTaskGuid; stackTracingIds[curID].Type = 0x62; // Flush Init curID++; } // Hard Faults if ((stackCapture & KernelTraceEventParser.Keywords.MemoryHardFaults) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x20; // Hard Fault curID++; } // Page Faults if ((stackCapture & KernelTraceEventParser.Keywords.MemoryPageFaults) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x0A; // Transition Fault curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x0B; // Demand zero Fault curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x0C; // Copy on Write Fault curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x0D; // Guard Page Fault curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.PageFaultTaskGuid; stackTracingIds[curID].Type = 0x0E; // Hard Page Fault curID++; // ! %02 49 ! Pagefile Mapped Section Create // ! %02 69 ! Pagefile Backed Image Mapping // ! %02 71 ! Contiguous Memory Generation } if ((stackCapture & KernelTraceEventParser.Keywords.FileIOInit) != 0) { // TODO allow stacks only on open and close; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x40; // Create curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x41; // Cleanup curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x42; // Close curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x43; // Read curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x44; // Write curID++; #if false stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x45; // SetInformation curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x46; // Delete curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x47; // Rename curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x48; // DirEnum curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x49; // Flush curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x4A; // QueryInformation curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x4B; // FSControl curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.FileIoTaskGuid; stackTracingIds[curID].Type = 0x4D; // DirNotify curID++; #endif } if ((stackCapture & KernelTraceEventParser.Keywords.Registry) != 0) { stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0A; // NtCreateKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0B; // NtOpenKey curID++; #if false stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0C; // NtDeleteKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0D; // NtQueryKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0E; // NtSetValueKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x0F; // NtDeleteValueKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x10; // NtQueryValueKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x11; // NtEnumerateKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x12; // NtEnumerateValueKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x13; // NtQueryMultipleValueKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x14; // NtSetInformationKey curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x15; // NtFlushKey curID++; // TODO What are these? stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x16; // KcbCreate curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x17; // KcbDelete curID++; stackTracingIds[curID].EventGuid = KernelTraceEventParser.RegistryTaskGuid; stackTracingIds[curID].Type = 0x1A; // VirtualizeKey curID++; #endif } // Confirm we did not overflow. Debug.Assert(curID <= stackTracingIdsMax); return curID; }