diff options
Diffstat (limited to 'src/debug/di/nativepipeline.h')
-rw-r--r-- | src/debug/di/nativepipeline.h | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/debug/di/nativepipeline.h b/src/debug/di/nativepipeline.h new file mode 100644 index 0000000000..627110806d --- /dev/null +++ b/src/debug/di/nativepipeline.h @@ -0,0 +1,221 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +//***************************************************************************** +// NativePipeline.h +// + +// +// defines native pipeline abstraction, which includes debug-support +// for event redirection. +//***************************************************************************** + + +#ifndef _NATIVE_PIPELINE_H +#define _NATIVE_PIPELINE_H + +//----------------------------------------------------------------------------- +// Interface for native-debugging pipeline associated with a single process +// that is being debugged. +// +// On windows, this is a wrapper around the win32 debugging API +// (eg, kernel32!WaitForDebugEvent). On rotor, it has an alternative implementation. +// . See code:IEventChannel for more information. +// @dbgtodo : All of the APIs that return BOOL should probably be changed to +// return HRESULTS so we don't have to rely on some implicit GetLastError protocol. +//----------------------------------------------------------------------------- +class INativeEventPipeline +{ +public: + // Call to delete the pipeline. This can only be called once. + virtual void Delete() = 0; + + + // + // set whether to kill outstanding debuggees when the debugger exits. + // + // Arguments: + // fKillOnExit - When the debugger thread (this thread) exits, outstanding debuggees will be + // terminated (if true), else detached (if false) + // + // Returns: + // True on success, False on failure. + // + // Notes: + // This is a cross-platform wrapper around Kernel32!DebugSetProcessKillOnExit. + // This affects all debuggees handled by this thread. + // This is not supported or necessary for Mac debugging. The only reason we need this on Windows is to + // ask the OS not to terminate the debuggee when the debugger exits. The Mac debugging pipeline + // doesn't automatically kill the debuggee when the debugger exits. + // + + virtual BOOL DebugSetProcessKillOnExit(bool fKillOnExit) = 0; + + // Create + virtual HRESULT CreateProcessUnderDebugger( + MachineInfo machineInfo, + LPCWSTR lpApplicationName, + LPCWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) = 0; + + // Attach + virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, DWORD processId) = 0; + + // Detach + virtual HRESULT DebugActiveProcessStop(DWORD processId) =0; + + // + // Block and wait for the next debug event from the debuggee process. + // + // Arguments: + // pEvent - buffer for the debug event to be returned + // dwTimeout - number of milliseconds to wait before timing out + // pProcess - the CordbProcess associated with this pipeline; used to look up a thread ID if necessary + // + // Return Value: + // TRUE if a debug event is available + // + // Notes: + // Once a debug event is returned, it is consumed from the pipeline and will not be accessible in the + // future. Caller is responsible for saving the debug event if necessary. + // + + virtual BOOL WaitForDebugEvent(DEBUG_EVENT * pEvent, DWORD dwTimeout, CordbProcess * pProcess) =0; + + // + // This is specific to Windows. When a debug event is sent to the debugger, the debuggee process is + // suspended. The debugger must call this function to resume the debuggee process. + // + // Arguments: + // dwProcessId - process ID of the debuggee + // dwThreadId - thread ID of the thread which has triggered a debug event before + // dwContinueStatus - whether to handle the exception (if any) reported on the specified thread + // + // Return Value: + // TRUE if successful + // + // Notes: + // For Mac debugging, the process isn't actually suspended when a debug event is raised. As such, + // this function is a nop for Mac debugging. See code:Debugger::SendRawEvent. + // + // Of course, this is a semantic difference from Windows. However, in most cases, the LS suspends + // all managed threads by calling code:Debugger::TrapAllRuntimeThreads immediately after raising a + // debug event. The only case where this is not true is code:Debugger::SendCreateProcess, but that + // doesn't seem to be a problem at this point. + // + + virtual BOOL ContinueDebugEvent( + DWORD dwProcessId, + DWORD dwThreadId, + DWORD dwContinueStatus + ) =0; + + // + // Return a handle for the debuggee process. + // + // Return Value: + // handle for the debuggee process (see below) + // + // Notes: + // Handles are a Windows-specific concept. For Mac debugging, the handle returned by this function is + // only valid for waiting on process termination. This is ok for now because the only cases where a + // real process handle is needed are related to interop-debugging, which isn't supported on the Mac. + // + + virtual HANDLE GetProcessHandle() = 0; + + // + // Terminate the debuggee process. + // + // Arguments: + // exitCode - the exit code for the debuggee process + // + // Return Value: + // TRUE if successful + // + // Notes: + // The exit code is ignored for Mac debugging. + // + + virtual BOOL TerminateProcess(UINT32 exitCode) = 0; + + // + // Resume any suspended threads in the currend process. + // This decreases the suspend count of each thread by at most 1. + // Call multiple times until it returns S_FALSE if you want to really ensure + // all threads are running. + // + // Notes: + // On Windows the OS may suspend threads when continuing a 2nd-chance exception. + // Call this to get them resumed again. On other platforms this + // will typically be a no-op, so I provide a default implementation to avoid + // everyone having to override this. + // + // Return Value: + // S_OK if at least one thread was resumed from a suspended state + // S_FALSE if nothing was done + // An error code indicating why we were not able to attempt this + + virtual HRESULT EnsureThreadsRunning() + { + return S_FALSE; + } +}; + +// +// Helper accessors for manipulating native pipeline. +// These also provide some platform abstractions for DEBUG_EVENT. +// + +// Returns process ID that the debug event is on. +DWORD GetProcessId(const DEBUG_EVENT * pEvent); + +// Returns Thread ID of the thread that fired the debug event. +DWORD GetThreadId(const DEBUG_EVENT * pEvent); + +// +// Determines if this is an exception event. +// +// Arguments: +// pEvent - [required, in]: debug event to inspect +// pfFirstChance - [required, out]: set if this is an 1st-chance exception. +// ppRecord - [required, out]: if this is an exception, pointer into to the exception record. +// this pointer has the same lifetime semantics as the DEBUG_EVENT (it may +// likely be a pointer into the debug-event). +// +// Returns: +// True if this is an exception. Sets outparameters to exception values. +// Else false. +// +// Notes: +// Exceptions are spceial because they need to be sent to the CLR for filtering. +BOOL IsExceptionEvent(const DEBUG_EVENT * pEvent, BOOL * pfFirstChance, const EXCEPTION_RECORD ** ppRecord); + + +//----------------------------------------------------------------------------- +// Allocate and return a pipeline object for this platform +// +// Returns: +// newly allocated pipeline object. Caller must call Dispose() on it. +INativeEventPipeline * NewPipelineForThisPlatform(); + +//----------------------------------------------------------------------------- +// Allocate and return a pipeline object for this platform +// Has debug checks (such as for event redirection) +// +// Returns: +// newly allocated pipeline object. Caller must call Dispose() on it. +INativeEventPipeline * NewPipelineWithDebugChecks(); + + + +#endif // _NATIVE_PIPELINE_H + |