/// <summary> /// Creates a new SimpleOutputHandler instances and sets it as the active handler for the debugger. /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> /// <param name="outputCallbacks"> /// An out parameter to receive the new SimpleOutputHandler. CALL Revert AND/OR Dipose TO /// REMOVE! /// </param> /// <param name="filter">An optional filter object to process the output data.</param> /// <param name="passThrough"> /// Whether the output data should be passed to the previously installed output handler. Default /// is to cache locally only. /// </param> /// <param name="passThroughOnly"> /// Disables local caching of output data. Save memory and is more effient when the primary /// goes it to pass the output data to the previously installed output handled (normally WinDbg). /// </param> /// <returns>Last HRESULT of the install process.</returns> public static int Install(DebugUtilities debugUtilities, out SimpleOutputHandler outputCallbacks, OUTPUT_FILTER filter = null, bool passThrough = false, bool passThroughOnly = false) { var oc = new SimpleOutputHandler(debugUtilities, debugUtilities, filter, passThrough, passThroughOnly); outputCallbacks = SUCCEEDED(oc.InstallationHRESULT) ? oc : null; return(oc.InstallationHRESULT); }
/// <summary> /// Creates a new SimpleDebugger object with the required parameters. /// </summary> /// <param name="originatingClient">An IDebugClient interface associated with the connection</param> /// <param name="processId">The ID of the process being debugged</param> /// <param name="connectionIsPassive">True if the debugger is passively attached to the target</param> /// <param name="outputHandler">A SimpleOutputHandler which is receiving the debugger output</param> /// <param name="eventHandler">A SimpleEventHandler to handle the debugger events</param> public SimpleDebugger(DebugUtilities originatingClient, uint processId, bool connectionIsPassive, SimpleOutputHandler outputHandler, SimpleEventHandler eventHandler) { _OriginatingDebugUtilities = originatingClient; ProcessID = processId; DebuggerIsPassive = connectionIsPassive; _OutputHandler = outputHandler; _EventHandler = eventHandler; }
private static int ConnectDebuggerDumpHelper(DebugUtilities debugUtilities, string dumpFile, out SimpleDebugger debuggerInformation) { int hr; 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; } hr = debugUtilities.DebugClient.OpenDumpFileWide(dumpFile, 0); if (FAILED(hr)) { goto ErrorWithDetach; } while (debuggerEventCallbacks.SessionIsActive == false) { hr = debugUtilities.DebugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50); if (FAILED(hr)) { goto ErrorWithDetach; } } debuggerInformation = new SimpleDebugger(debugUtilities, 0, true, 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); }
/// <summary> /// Creates a new SimpleOutputHandler instances and sets it as the active handler for the debugger. /// </summary> /// <param name="debugUtilities">A DebugUtilities associated with the debugger.</param> /// <param name="executionUtilities"> /// An utilities associated with the output handler. This interface should be used for all /// actions where output should be redirected to the output handler. /// </param> /// <param name="outputCallbacks"> /// An out parameter to receive the new SimpleOutputHandler. CALL Revert AND/OR Dipose TO /// REMOVE! /// </param> /// <param name="filter">An optional filter object to process the output data.</param> /// <param name="passThrough"> /// Whether the output data should be passed to the previously installed output handler. Default /// is to cache locally only. /// </param> /// <param name="passThroughOnly"> /// Disables local caching of output data. Save memory and is more effient when the primary /// goes it to pass the output data to the previously installed output handled (normally WinDbg). /// </param> /// <returns>Last HRESULT of the install process.</returns> public static int Install(DebugUtilities debugUtilities, out DebugUtilities executionUtilities, out SimpleOutputHandler outputCallbacks, OUTPUT_FILTER filter = null, bool passThrough = false, bool passThroughOnly = false) { IDebugClient executionClient; int hr = debugUtilities.DebugClient.CreateClient(out executionClient); if (FAILED(hr)) { debugUtilities.OutputVerboseLine("SimpleOutputHandler.Install Failed creating a new debug client for execution: {0:x8}", hr); outputCallbacks = null; executionUtilities = null; return(hr); } executionUtilities = new DebugUtilities(executionClient); var oc = new SimpleOutputHandler(executionUtilities, debugUtilities, filter, passThrough, passThroughOnly); outputCallbacks = SUCCEEDED(oc.InstallationHRESULT) ? oc : null; return(oc.InstallationHRESULT); }
/// <summary> /// Detaches from the target process /// </summary> public void Detach(bool detaching) { if (Detached == false && detaching == true) { if (OutputHandler != null) { OutputHandler.Dispose(); _OutputHandler = null; } if (EventHandler != null) { EventHandler.Dispose(); _EventHandler = null; } if (OriginatingDebugUtilities != null) { OriginatingDebugUtilities.DebugClient.DetachProcesses(); OriginatingDebugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH); DebugUtilities.ReleaseComObjectSafely(OriginatingDebugUtilities); _OriginatingDebugUtilities = null; } Detached = true; } }
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); }