Example #1
0
        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);
            }
        }
Example #2
0
 public DebuggerThread(IDebugClient client, Symbols symbols)
 {
     _symbols       = symbols;
     _control5      = (IDebugControl5)client;
     _advanced2     = (IDebugAdvanced2)client;
     _systemObjects = (IDebugSystemObjects)client;
 }
Example #3
0
 /// <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));
        }
Example #5
0
        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);
        }
Example #6
0
 /// <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;
     }
 }
Example #7
0
        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);
        }