private void CreateClient(IDebugClient client) { DebuggerInterface = client; _spaces = (IDebugDataSpaces)DebuggerInterface; _spacesPtr = (IDebugDataSpacesPtr)DebuggerInterface; _symbols = (IDebugSymbols)DebuggerInterface; _control = (IDebugControl2)DebuggerInterface; // These interfaces may not be present in older DbgEng dlls. _spaces2 = DebuggerInterface as IDebugDataSpaces2; _symbols3 = DebuggerInterface as IDebugSymbols3; _advanced = DebuggerInterface as IDebugAdvanced; _systemObjects = DebuggerInterface as IDebugSystemObjects; _systemObjects3 = DebuggerInterface as IDebugSystemObjects3; Interlocked.Increment(ref s_totalInstanceCount); if (_systemObjects3 == null && s_totalInstanceCount > 1) { throw new ClrDiagnosticsException("This version of DbgEng is too old to create multiple instances of DataTarget.", ClrDiagnosticsExceptionKind.DebuggerError); } if (_systemObjects3 != null) { _systemObjects3.GetCurrentSystemId(out _instance); } }
public DebuggerThread(IDebugClient client, Symbols symbols) { _symbols = symbols; _control5 = (IDebugControl5)client; _advanced2 = (IDebugAdvanced2)client; _systemObjects = (IDebugSystemObjects)client; }
/// <summary> /// Initializes a new instance of the <see cref="DebugEngineProxy" /> class. /// </summary> /// <param name="control">The control.</param> /// <param name="client">The client.</param> /// <param name="registers">The registers.</param> /// <param name="systemObjects">The system objects.</param> /// <param name="debugDataSpaces">The debug data spaces.</param> public DebugEngineProxy(IDebugControl6 control, IDebugClient5 client, IDebugRegisters2 registers, IDebugSystemObjects systemObjects, IDebugDataSpaces debugDataSpaces, IExecuteWrapper executeWrapper) { Control = control; Client = client; Registers = registers; Dataspaces = debugDataSpaces; ExecuteWrapper = executeWrapper; RegisterEngine = new RegisterEngine(); // todo: inject MemoryEngine = new MemoryEngine(); SystemObjects = systemObjects; Is32Bit = Regex.Match(ExecuteWrapper.Execute("!peb"), @"PEB at (?<peb>[a-fA-F0-9]+)").Groups["peb"].Value .Length == 8; }
public WindowsDebugEngine(string winDbgPath) { logger.Debug("WindowsDebugEngine"); object obj = null; Guid clsid = CLSID(typeof(IDebugClient5)); this.winDbgPath = winDbgPath; hDll = LoadWin32Library(Path.Combine(winDbgPath, "dbgeng.dll")); hProc = GetProcAddress(hDll, "DebugCreate"); DebugCreate debugCreate = (DebugCreate)Marshal.GetDelegateForFunctionPointer(hProc, typeof(DebugCreate)); if (debugCreate(ref clsid, out obj) != 0) { Debugger.Break(); } dbgClient = (IDebugClient5)obj; dbgControl = (IDebugControl4)obj; dbgSymbols = (IDebugSymbols3)obj; dbgSystemObjects = (IDebugSystemObjects)obj; // Reset events loadModules.Reset(); exitProcess.Reset(); handlingException.Reset(); handledException.Reset(); exitDebugger.Reset(); // Reset output output = new StringBuilder(); dbgSymbols.SetSymbolPath(@"SRV*http://msdl.microsoft.com/download/symbols"); dbgClient.SetOutputCallbacks(new OutputCallbacks(this)); dbgClient.SetEventCallbacks(new EventCallbacks(this)); }
private ulong GetStacksSize(DataTarget target) { // Find all the TEBs and then sum StackBase - StackLimit for all of them. // This gives us the committed size for each thread, but we don't have the // reserved size (which is the actual address space consumed). Theoretically, // we could get it from enumerating the memory region adjacent to the committed // pages and the guard page that follows. Also, for WoW64 threads, we are only // reporting the x86 stack (the x64 stack doesn't live in the 4GB address space // anyway, so it's not that relevant). IDebugSystemObjects sysObjects = (IDebugSystemObjects)target.DebuggerInterface; uint numThreads; HR.Verify(sysObjects.GetNumberThreads(out numThreads)); ulong totalCommit = 0; for (uint i = 0; i < numThreads; ++i) { HR.Verify(sysObjects.SetCurrentThreadId(i)); ulong tebAddress; HR.Verify(sysObjects.GetCurrentThreadTeb(out tebAddress)); int read; byte[] teb = new byte[IntPtr.Size * 3]; // ExceptionList, StackBase, StackLimit if (target.ReadProcessMemory(tebAddress, teb, teb.Length, out read) && read == teb.Length) { ulong stackBase = AddressFromBytes(teb, IntPtr.Size); ulong stackLimit = AddressFromBytes(teb, IntPtr.Size * 2); totalCommit = stackBase - stackLimit; } } return(totalCommit); }
/// <summary> /// Initializes the API. /// </summary> /// <param name="log">The log.</param> internal static void InitApi(ILog log = null) { LastHR = HRESULT.S_OK; if (client != null) { return; } try { log?.Debug("Client did not exist. Creating a new client and associated interfaces."); client = (IDebugClient5)CreateIDebugClient(); control = (IDebugControl6)client; registers = (IDebugRegisters2)client; symbols = (IDebugSymbols5)client; systemObjects = (IDebugSystemObjects)client; debugDataSpaces = (IDebugDataSpaces)client; } catch (Exception e) { log?.Fatal("Unable to create debug client. Are you missing DLLs?"); log?.Fatal(e); LastHR = HRESULT.E_UNEXPECTED; } }
private void CreateClient(IDebugClient client) { _client = client; _spaces = (IDebugDataSpaces)_client; _spacesPtr = (IDebugDataSpacesPtr)_client; _symbols = (IDebugSymbols)_client; _control = (IDebugControl2)_client; // These interfaces may not be present in older DbgEng dlls. _spaces2 = _client as IDebugDataSpaces2; _symbols3 = _client as IDebugSymbols3; _advanced = _client as IDebugAdvanced; _systemObjects = _client as IDebugSystemObjects; _systemObjects3 = _client as IDebugSystemObjects3; Interlocked.Increment(ref s_totalInstanceCount); if (_systemObjects3 == null && s_totalInstanceCount > 1) throw new ClrDiagnosticsException("This version of DbgEng is too old to create multiple instances of DataTarget.", ClrDiagnosticsException.HR.DebuggerError); if (_systemObjects3 != null) _systemObjects3.GetCurrentSystemId(out _instance); }
private static int ConnectDebuggerLiveHelper(DebugUtilities debugUtilities, uint processID, bool passive, out SimpleDebugger debuggerInformation) { int hr; IDebugControl debugControl = null; IDebugSystemObjects debugSystemObjects = null; SimpleOutputHandler debuggerOutputCallbacks = null; SimpleEventHandler debuggerEventCallbacks = null; debuggerInformation = null; hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks); if (hr != S_OK) { goto Error; } hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks); if (hr != S_OK) { goto ErrorWithDetach; } DEBUG_ATTACH attachFlags = passive ? DEBUG_ATTACH.NONINVASIVE | DEBUG_ATTACH.NONINVASIVE_NO_SUSPEND : DEBUG_ATTACH.INVASIVE_RESUME_PROCESS; hr = debugUtilities.DebugClient.AttachProcess(0, processID, attachFlags); if (hr != S_OK) { goto ErrorWithDetach; } while (debuggerEventCallbacks.SessionIsActive == false) { hr = debugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50); if (FAILED(hr)) { goto ErrorWithDetach; } } bool foundMatchingProcess = false; uint numProcesses; debugSystemObjects.GetNumberProcesses(out numProcesses); uint[] systemProcessIDs = new uint[numProcesses]; uint[] engineProcessIDs = new uint[numProcesses]; hr = debugSystemObjects.GetProcessIdsByIndex(0, numProcesses, engineProcessIDs, systemProcessIDs); for (uint i = 0; i < numProcesses; ++i) { if (systemProcessIDs[i] == processID) { foundMatchingProcess = true; hr = debugSystemObjects.SetCurrentProcessId(engineProcessIDs[i]); if (FAILED(hr)) { debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! Failed to set the active process! hr={0:x8}", hr)); goto ErrorWithDetach; } break; } } if (foundMatchingProcess == false) { hr = E_FAIL; debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! The debugger engine could not find the requested process ID ({0})!", processID)); goto ErrorWithDetach; } debuggerInformation = new SimpleDebugger(debugUtilities, processID, passive, debuggerOutputCallbacks, debuggerEventCallbacks); goto Exit; ErrorWithDetach: debugUtilities.DebugClient.DetachProcesses(); debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH); Error: if (debuggerEventCallbacks != null) { debuggerEventCallbacks.Dispose(); } if (debuggerOutputCallbacks != null) { debuggerOutputCallbacks.Dispose(); } Exit: return(hr); }