/// <summary> /// Determines the platform architecture the OS is running a process in. Wow mode processes /// will report INTEL (32bit) otherwise all processes run in the native system architecture /// </summary> static public ProcessorArchitecture GetArchitectureFromPid(int pid) { NativeMethods.SYSTEM_INFO info; NativeMethods.GetSystemInfo(out info); bool isWow = false; if (info.wProcessorArchitecture == ProcessorArchitecture.PROCESSOR_ARCHITECTURE_INTEL) { // We know that we need an x86 context return(ProcessorArchitecture.PROCESSOR_ARCHITECTURE_INTEL); } else { // We cannot make this call if we know we're executing on a 32-bit OS, so we wait until // we know that we're running under a 64-bit OS where this method is defined. // 0x0400 = PROCESS_QUERY_INFORMATION using (SafeWin32Handle hProcess = NativeMethods.OpenProcess(0x0400, false, pid)) { NativeMethods.IsWow64Process(hProcess, ref isWow); } if (isWow) { // Even though we're running on a 64-bit OS, we are currently in WOW mode. return(ProcessorArchitecture.PROCESSOR_ARCHITECTURE_INTEL); } // From this point on, we know that we're not running a 32-bit OS. We can fully trust the // value in wProcessorArchitecture else { return(info.wProcessorArchitecture); } } }
/// <summary> /// Attach to a process with the given Process ID /// Only debug the specified CLR version; all others are ignored. /// </summary> /// <param name="processId">The Process ID to attach to.</param> /// <param name="attachContinuationEvent">A OS event handle which must be set to unblock the debuggee /// when first continuing from attach</param> /// <param name="version">The version string for the CLR instance to debug.</param> /// <returns>The resulting MDbgProcess.</returns> public MDbgProcess Attach(int processId, Microsoft.Samples.Debugging.Native.SafeWin32Handle attachContinuationEvent, string version) { Debug.Assert(version != null); MDbgProcess p = m_processMgr.CreateLocalProcess(new CorDebugger(version)); p.Attach(processId, attachContinuationEvent); return(p); }
public static extern bool SetEvent(SafeWin32Handle eventHandle);
public static extern SafeMapViewHandle MapViewOfFile(SafeWin32Handle hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);
public static extern bool IsWow64Process(SafeWin32Handle hProcess, ref bool isWow);
public static void AttachCmd(string arguments) { const string versionArg = "ver"; const string continuationEventArg = "attachEvent"; const string pidArg = "pid"; ArgParser ap = new ArgParser(arguments, versionArg + ":1;" + continuationEventArg + ":1;" + pidArg + ":1"); if (ap.Count > 1) { throw new MDbgShellException("Wrong # of arguments."); } if (!ap.Exists(0) && !ap.OptionPassed(pidArg)) { WriteOutput("Please choose some process to attach"); ProcessEnumCmd(""); return; } int pid; if (ap.Exists(0)) { pid = ap.AsInt(0); if (ap.OptionPassed(pidArg)) { WriteOutput("Do not specify pid option when also passing pid as last argument"); return; } } else { Debug.Assert(ap.OptionPassed(pidArg)); // verified above pid = ap.GetOption(pidArg).AsInt; } // // Do some sanity checks to give useful end-user errors. // // Can't attach to ourselves! if (Process.GetCurrentProcess().Id == pid) { throw new MDbgShellException("Cannot attach to myself!"); } // Can't attach to a process that we're already debugging. // ICorDebug may enforce this, but the error may not be very descriptive for an end-user. // For example, ICD may propogate an error from the OS, and the OS may return // something like AccessDenied if another debugger is already attached. // This only checks for cases where this same instance of MDbg is already debugging // the process of interest. foreach (MDbgProcess procOther in Debugger.Processes) { if (pid == procOther.CorProcess.Id) { throw new MDbgShellException("Can't attach to process " + pid + " because it's already being debugged"); } } // Get the OS handle if there was one SafeWin32Handle osEventHandle = null; if (ap.OptionPassed(continuationEventArg)) { osEventHandle = new SafeWin32Handle(new IntPtr(ap.GetOption(continuationEventArg).AsHexOrDecInt)); } // determine the version to attach to string version = null; if (ap.OptionPassed(versionArg)) { version = ap.GetOption(versionArg).AsString; } else { version = MdbgVersionPolicy.GetDefaultAttachVersion(pid); } if (version == null) { throw new MDbgShellException("Can't determine what version of the CLR to attach to in process " + pid + ". Use -ver to specify a version"); } // attach MDbgProcess p; p = Debugger.Attach(pid, osEventHandle, version); p.Go().WaitOne(); if (osEventHandle != null) { osEventHandle.Dispose(); } }
public static extern bool SetEvent(SafeWin32Handle eventHandle);
public static extern SafeMapViewHandle MapViewOfFile(SafeWin32Handle hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap);
public static extern bool IsWow64Process(SafeWin32Handle hProcess, ref bool isWow);
public void Attach(int processId, SafeWin32Handle attachContinuationEvent, CorRemoteTarget target) { Debug.Assert(!IsAlive); if (IsAlive) throw new InvalidOperationException("cannot call Attach on active process"); m_stopGo = new V2StopGoController(this); m_processAttaching = true; try { m_corProcess = m_corDebugger.DebugActiveProcess(processId,/*win32Attach*/ false, target); NativeProcessCreated(); } catch { // if an attach fails, we need to remove the process object from active processes. CleanAfterProcessExit(); throw; } // User's breakpoint should start with number 0. When launching, 1st breakpoint created is // special -- user entry point and it's given number 0. // In case of attach we don't create any such breakpoint but we still want // to start numbering breakpoints with 1; therefore we'll increase free breakpoint number. if (Breakpoints.m_freeBreakpointNumber == 0) { Breakpoints.m_freeBreakpointNumber = 1; } InitDebuggerCallbacks(); // resume the debuggee // for pure managed debugging this is legal as long as DebugActiveProcess has returned if (attachContinuationEvent != null) { Microsoft.Samples.Debugging.Native.NativeMethods.SetEvent(attachContinuationEvent); attachContinuationEvent.Close(); } }
/// <summary> /// Attach to a process by Process ID (PID) /// </summary> /// <param name="processId">The PID to attach to.</param> /// <param name="attachContinuationEvent">A OS event handle which must be set to unblock the debuggee /// when first continuing from attach</param> public void Attach(int processId, SafeWin32Handle attachContinuationEvent) { Attach(processId, attachContinuationEvent, null); }