/// <summary> /// Continue a debug event previously gotten by WaitForDebugEvent /// </summary> /// <param name="nativeEvent"></param> /// <remarks>Can't continue a debug event if we just detached from the process</remarks> public void ContinueEvent(NativeEvent nativeEvent) { if (nativeEvent == null) { throw new ArgumentNullException("nativeEvent"); } if (nativeEvent.ContinueStatus == NativeMethods.ContinueStatus.CONTINUED) { throw new ArgumentException("event was already continued", "nativeEvent"); } if (nativeEvent.Pipeline != this) { throw new ArgumentException("event does not belong to this pipeline"); } // Verify that the process for this event is still connected to our pipeline. // The lookup will throw if the process detached or was terminated. NativeDbgProcess proc = nativeEvent.Process; Debug.Assert(proc.Id == nativeEvent.ProcessId); nativeEvent.DoCleanupForContinue(); bool fContinueOk = NativeMethods.ContinueDebugEvent((uint)nativeEvent.ProcessId, (uint)nativeEvent.ThreadId, nativeEvent.ContinueStatus); if (!fContinueOk) { int err = Marshal.GetLastWin32Error(); throw new InvalidOperationException("Continue failed on process " + nativeEvent.ProcessId + " error=" + err); } // Mark as continued so that we don't accidentally continue again. nativeEvent.ContinueStatus = NativeMethods.ContinueStatus.CONTINUED; }
internal static void SkipInitialDebugBreak(uint dwProcessId) { if (!NativeDebuggingMethods.DebugActiveProcess(dwProcessId)) { throw new LastWin32Exception(); } try { bool done = false; uint mainThread = 0; while (!done) { dynamic debugEvent = null; if (!WaitForDebugEvent(ref debugEvent, (int)TimeSpan.FromSeconds(10).TotalMilliseconds)) { throw new LastWin32Exception(); } switch ((NativeDebugEventCode)debugEvent.header.dwDebugEventCode) { case NativeDebugEventCode.CREATE_PROCESS_DEBUG_EVENT: new SafeFileHandle(debugEvent.union.CreateProcess.hFile, true).Dispose(); break; case NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT: new SafeFileHandle(debugEvent.union.LoadDll.hFile, true).Dispose(); break; case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT: case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT: mainThread = debugEvent.header.dwThreadId; done = true; break; } if (!NativeDebuggingMethods.ContinueDebugEvent(debugEvent.header.dwProcessId, debugEvent.header.dwThreadId, NativeDebuggingMethods.ContinueStatus.DBG_CONTINUE)) { throw new LastWin32Exception(); } } SuspendThread(new IntPtr(mainThread)); } finally { if (!NativeDebuggingMethods.DebugActiveProcessStop(dwProcessId)) { throw new LastWin32Exception(); } } }