private void Initialize(ICollection <string> pathItems = null) { StringBuilder searchPathBuilder = null; if (null != pathItems) { searchPathBuilder = new StringBuilder(); } int thisHandleValue; lock (Globals.DebugHelpLock) { _lastAllocatedHandle += IntPtr.Size; thisHandleValue = _lastAllocatedHandle; } base.SetHandle(new IntPtr(thisHandleValue)); string searchPath = (null == searchPathBuilder) ? null : searchPathBuilder.ToString(); if (!DbgHelp.SymInitialize(base.handle, searchPath, false)) { Trace.TraceError( "Failed to create symbol handler for path '{0}'. Error : 0x{1:X8}", searchPath ?? "<NULL>", Marshal.GetLastWin32Error()); throw new SymbolHandlingException(); } // Set default, reasonable search path. this.SearchPath = string.Format( @"srv*{0}\symbols*https://msdl.microsoft.com/download/symbols", Environment.GetEnvironmentVariable("SystemDrive") ?? "C:"); // TODO : Also attempt to check the DBGHELP.DLL version. }
/// <summary> /// Looks through the configured symbol paths to find a PDB symbol /// file matching specified name, GUID and age parameters. /// </summary> /// <param name="pdbFileName"></param> /// <param name="guid"></param> /// <param name="age"></param> /// <returns></returns> /// <remarks> /// Note how we don't have to have a module loaded to find its PDB, /// we just look for a PDB file using name, GUID and age. These are /// the parameters that can be extracted from module's PE header, /// in the Debug Directory section. /// </remarks> public string FindPdbFile(string pdbFileName, Guid guid, int age) { DbgHelp.SymSetOptions(DbgHelp.SYMOPT_DEBUG); var hProcess = new IntPtr(1); #if TARGET_NET_20 var searchPath = string.Join(";", this.SymbolPaths.ToArray()); #else var searchPath = string.Join(";", this.SymbolPaths); #endif DbgHelp.SymInitialize(hProcess, searchPath, false); var filePath = new StringBuilder(256); var guidHandle = GCHandle.Alloc(guid, GCHandleType.Pinned); try { if (!DbgHelp.SymFindFileInPath(hProcess, null, pdbFileName, guidHandle.AddrOfPinnedObject(), (uint)age, 0, DbgHelp.SSRVOPT_GUIDPTR, filePath, null, IntPtr.Zero)) { return(null); } } finally { guidHandle.Free(); DbgHelp.SymCleanup(hProcess); } return(filePath.ToString()); }
public static Symbol[] GetSymbols(string DllFile) { IntPtr CurProc = Process.GetCurrentProcess().Handle; DbgHelp.SymInitialize(CurProc, null, false); if (!File.Exists(DllFile)) { throw new FileNotFoundException("File not found", DllFile); } List <Symbol> Symbols = new List <Symbol>(); ulong DllBase = DbgHelp.SymLoadModuleEx(CurProc, IntPtr.Zero, DllFile, null, 0, 0, IntPtr.Zero, 0); DbgHelp.SymEnumerateSymbols64(CurProc, DllBase, (Name, Addr, Size, Ctx) => { Symbols.Add(new Symbol(Name, DllBase - Addr, Size)); return(true); }, IntPtr.Zero); DbgHelp.SymCleanup(CurProc); return(Symbols.ToArray()); }
public StackTrace(uint ProcessId, uint ThreadId) { List <StackCall> StackCalls = new List <StackCall>(); //StackWalk64 Callbacks DbgHelp.SymFunctionTableAccess64Delegate FunctionTableAccessRoutine = new DbgHelp.SymFunctionTableAccess64Delegate(DbgHelp.SymFunctionTableAccess64); DbgHelp.SymGetModuleBase64Delegate GetModuleBaseRoutine = new DbgHelp.SymGetModuleBase64Delegate(DbgHelp.SymGetModuleBase64); IntPtr lpContextRecord = new IntPtr(); STACKFRAME64 StackFrame = new STACKFRAME64(); //Get handle for thread and its process IntPtr hProcess = Kernel32.OpenProcess(ProcessAccess.All, false, ProcessId); IntPtr hThread = Kernel32.OpenThread(ThreadAccess.All, false, ThreadId); //Initialize Symbol handler DbgHelp.SymInitialize(hProcess, null, false); //Determine Image & Processor types bool Wow64 = false; uint ProcessorType = Functions.GetProcessorType(); if (ProcessorType == (uint)ImageFileMachine.AMD64 | ProcessorType == (uint)ImageFileMachine.IA64) { Wow64 = Functions.IsWow64(hProcess); } //Initialize thread context & stack frame based on architectures if (Wow64) { ProcessorType = (uint)ImageFileMachine.I386; //Load 32-bit modules for symbol access Functions.LoadModules(hProcess, ListModules._32Bit); //Initialize an X86_CONTEXT X86_CONTEXT ContextRecord = new X86_CONTEXT(); ContextRecord.ContextFlags = (uint)ContextFlags.X86ContextAll; lpContextRecord = Marshal.AllocHGlobal(Marshal.SizeOf(ContextRecord)); Marshal.StructureToPtr(ContextRecord, lpContextRecord, false); //Get context of thread Kernel32.Wow64SuspendThread(hThread); Kernel32.Wow64GetThreadContext(hThread, lpContextRecord); //Initialize Stack frame for first call to StackWalk64 ContextRecord = (X86_CONTEXT)Marshal.PtrToStructure(lpContextRecord, typeof(X86_CONTEXT)); StackFrame = Functions.InitializeStackFrame64 (AddressMode.Flat, ContextRecord.Eip, ContextRecord.Esp, ContextRecord.Ebp, new ulong()); } else if (ProcessorType == (uint)ImageFileMachine.I386) { ProcessorType = (uint)ImageFileMachine.I386; //Load 32-bit modules for symbol access Functions.LoadModules(hProcess, ListModules._32Bit); //Initialize an X86_CONTEXT X86_CONTEXT ContextRecord = new X86_CONTEXT(); ContextRecord.ContextFlags = (uint)ContextFlags.X86ContextAll; lpContextRecord = Marshal.AllocHGlobal(Marshal.SizeOf(ContextRecord)); Marshal.StructureToPtr(ContextRecord, lpContextRecord, false); //Get context of thread Kernel32.SuspendThread(hThread); Kernel32.GetThreadContext(hThread, lpContextRecord); //Initialize Stack frame for first call to StackWalk64 ContextRecord = (X86_CONTEXT)Marshal.PtrToStructure(lpContextRecord, typeof(X86_CONTEXT)); StackFrame = Functions.InitializeStackFrame64 (AddressMode.Flat, ContextRecord.Eip, ContextRecord.Esp, ContextRecord.Ebp, new ulong()); } else if (ProcessorType == (uint)ImageFileMachine.AMD64) { //Load 64-bit modules for symbol access Functions.LoadModules(hProcess, ListModules._64Bit); //Initialize AMD64_CONTEXT AMD64_CONTEXT ContextRecord = new AMD64_CONTEXT(); ContextRecord.ContextFlags = (uint)ContextFlags.AMD64ContextAll; lpContextRecord = Marshal.AllocHGlobal(Marshal.SizeOf(ContextRecord)); Marshal.StructureToPtr(ContextRecord, lpContextRecord, false); //Get context of thread Kernel32.SuspendThread(hThread); Kernel32.GetThreadContext(hThread, lpContextRecord); //Initialize Stack frame for first call to StackWalk64 ContextRecord = (AMD64_CONTEXT)Marshal.PtrToStructure(lpContextRecord, typeof(AMD64_CONTEXT)); StackFrame = Functions.InitializeStackFrame64 (AddressMode.Flat, ContextRecord.Rip, ContextRecord.Rsp, ContextRecord.Rsp, new ulong()); } else if (ProcessorType == (uint)ImageFileMachine.IA64) { //Load 64-bit modules for symbol access Functions.LoadModules(hProcess, ListModules._64Bit); //Initialize IA64_CONTEXT IA64_CONTEXT ContextRecord = new IA64_CONTEXT(); ContextRecord.ContextFlags = (uint)ContextFlags.IA64ContextAll; lpContextRecord = Marshal.AllocHGlobal(Marshal.SizeOf(ContextRecord)); Marshal.StructureToPtr(ContextRecord, lpContextRecord, false); //Get context of thread Kernel32.SuspendThread(hThread); Kernel32.GetThreadContext(hThread, lpContextRecord); //Initialize Stack frame for first call to StackWalk64 ContextRecord = (IA64_CONTEXT)Marshal.PtrToStructure(lpContextRecord, typeof(IA64_CONTEXT)); StackFrame = Functions.InitializeStackFrame64 (AddressMode.Flat, ContextRecord.StIIP, ContextRecord.IntSp, ContextRecord.RsBSP, ContextRecord.IntSp); } //Marshal stack frame to unmanaged memory IntPtr lpStackFrame = Marshal.AllocHGlobal(Marshal.SizeOf(StackFrame)); Marshal.StructureToPtr(StackFrame, lpStackFrame, false); //Walk the Stack for (int frameNum = 0; ; frameNum++) { //Get Stack frame DbgHelp.StackWalk64(ProcessorType, hProcess, hThread, lpStackFrame, lpContextRecord, null, FunctionTableAccessRoutine, GetModuleBaseRoutine, null); StackFrame = (STACKFRAME64)Marshal.PtrToStructure(lpStackFrame, typeof(STACKFRAME64)); if (StackFrame.AddrReturn.Offset == 0) { break; } //End of stack reached StackCalls.Add(new StackCall(hProcess, StackFrame.AddrPC.Offset, StackFrame.AddrReturn.Offset, (int)ThreadId)); } Calls = StackCalls.ToArray(); //Cleanup DbgHelp.SymCleanup(hProcess); Marshal.FreeHGlobal(lpStackFrame); Marshal.FreeHGlobal(lpContextRecord); Kernel32.ResumeThread(hThread); Kernel32.CloseHandle(hThread); Kernel32.CloseHandle(hProcess); }