// // IEnumerator interface // public bool MoveNext() { ICorDebugProcess[] a = new ICorDebugProcess[1]; uint c = 0; int r = m_enum.Next ((uint) a.Length, a, out c); if (r==0 && c==1) // S_OK && we got 1 new element m_proc = CorProcess.GetCorProcess(a[0]); else m_proc = null; return m_proc != null; }
public void Debug(int processID) { debugger = new CorDebugger(CorDebugger.GetDefaultDebuggerVersion()); process = debugger.DebugActiveProcess(processID, false); process.OnException += OnException; process.OnCreateAppDomain += OnNewAppDomain; process.OnProcessExit += OnExit; process.OnModuleLoad += OnModuleLoad; process.OnBreakpoint += OnBreakpoint; process.OnStepComplete += OnStepComplete; process.Continue(false); state = ProcessState.Started; subscriber.Published(string.Format("Successfully attached to Process with ID [{0}]", processID)); }
public static CorProcess GetCorProcess(ICorDebugProcess process) { Debug.Assert(process != null); lock (m_instances) { if (!m_instances.Contains(process)) { CorProcess p = new CorProcess(process); m_instances.Add(process, p); return p; } return (CorProcess)m_instances[process]; } }
/// <summary> /// Given a LoadModule debug event (and the process), get the ImageName /// </summary> /// <param name="corProcess"> The CorProcess where this image is loaded.</param> /// <param name="eventLoadDll"> The LOAD_DLL_DEBUG_INFO event.</param> /// <returns> The image name or null if it couldn't be determined from the event</returns> private static string GetImageNameFromDebugEvent(CorProcess corProcess, LOAD_DLL_DEBUG_INFO eventLoadDll) { string moduleName; bool bUnicode = eventLoadDll.fUnicode!=0; if(eventLoadDll.lpImageName == IntPtr.Zero) { return null; } else { byte[] buffer = new byte[4]; int bytesRead = corProcess.ReadMemory(eventLoadDll.lpImageName.ToInt64(),buffer); Debug.Assert(bytesRead==buffer.Length); IntPtr newptr=new IntPtr((int)buffer[0]+((int)buffer[1]<<8)+((int)buffer[2]<<16)+((int)buffer[3]<<24)); if(newptr == IntPtr.Zero) { return null; } else { System.Text.StringBuilder sb = new System.Text.StringBuilder(); if(bUnicode) buffer = new byte[2]; else buffer = new byte[1]; do { bytesRead = corProcess.ReadMemory(newptr.ToInt64(),buffer); Debug.Assert(bytesRead==buffer.Length); if(bytesRead<buffer.Length) break; int b; if(bUnicode) b=(int)buffer[0]+((int)buffer[1]<<8); else b=(int)buffer[0]; if(b==0) break; sb.Append((char)b); newptr=new IntPtr(newptr.ToInt32()+2); } while(true); moduleName = sb.ToString(); } } return moduleName; }
public CorAppDomainEventArgs(CorProcess process, CorAppDomain ad) : base(process) { m_ad = ad; }
public CorProcessEventArgs(CorProcess process) : base(process) { }
// Thread may be null. public CorMDAEventArgs(CorMDA mda, CorThread thread, CorProcess proc) : base(proc) { m_mda = mda; Thread = thread; //m_proc = proc; }
public CorDebuggerErrorEventArgs(CorProcess process, int hresult, int errorCode) : base(process) { m_hresult = hresult; m_errorCode = errorCode; }
// returns string that contains a human-readable content of DEBUG_EVENT passed in internal static string DebugEventToString(CorProcess corProcess,DEBUG_EVENT debugEvent) { string callArgs;// = new StringBuilder(); switch((NativeDebugEventCode)debugEvent.dwDebugEventCode) { case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXCEPTION_DEBUG_EVENT: FirstChance: {0} ExceptionCode: 0x{1:x} ExceptionFlags: 0x{2:x} Address: 0x{3:x} ", new Object[]{ (debugEvent.Exception.dwFirstChance!=0?true:false), debugEvent.Exception.ExceptionRecord.ExceptionCode, debugEvent.Exception.ExceptionRecord.ExceptionFlags, (int)debugEvent.Exception.ExceptionRecord.ExceptionAddress}); //<strip>@TODO For AV add written from /to</strip> break; case NativeDebugEventCode.CREATE_THREAD_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" CREATE_THREAD_DEBUG_EVENT: ThreadLocalBase: 0x{0:x} StartAddress: 0x{1:x} ", new Object[]{ (int)debugEvent.CreateThread.lpThreadLocalBase, (int)debugEvent.CreateThread.lpStartAddress}); break; case NativeDebugEventCode.EXIT_THREAD_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXIT_THREAD_DEBUG_EVENT: ExitCode: 0x{0:x} ", new Object[]{ debugEvent.ExitThread.dwExitCode}); break; case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXIT_PROCESS_DEBUG_EVENT: ExitCode: 0x{0:x} ", new Object[]{ debugEvent.ExitProcess.dwExitCode}); break; case NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT: { string moduleName = GetImageNameFromDebugEvent(corProcess, debugEvent.LoadDll); if(moduleName == null) { if (debugEvent.LoadDll.lpImageName == IntPtr.Zero) moduleName = "N/A (lpImageName==null)"; else moduleName = "N/A (in process)"; } callArgs = String.Format(CultureInfo.InvariantCulture, @" LOAD_DLL_DEBUG_EVENT: BaseAddress: 0x{0:x} ModuleName: {1} ", new Object[]{ (int)debugEvent.LoadDll.lpBaseOfDll, moduleName}); break; } case NativeDebugEventCode.OUTPUT_DEBUG_STRING_EVENT: { string message = GetMessageFromDebugEvent(corProcess,debugEvent.OutputDebugString); callArgs = String.Format(CultureInfo.InvariantCulture, @" OUTPUT_DEBUG_STRING_EVENT: text: {0} ", new Object[]{ message}); break; } default: callArgs = String.Format(CultureInfo.InvariantCulture, @" {0}: ", new Object[]{ ((NativeDebugEventCode)debugEvent.dwDebugEventCode) }); break; } return callArgs; }
// returns string that contains a human-readable content of DEBUG_EVENT passed in internal static string DebugEventToString(CorProcess corProcess, DEBUG_EVENT debugEvent) { string callArgs;// = new StringBuilder(); switch ((NativeDebugEventCode)debugEvent.dwDebugEventCode) { case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXCEPTION_DEBUG_EVENT: FirstChance: {0} ExceptionCode: 0x{1:x} ExceptionFlags: 0x{2:x} Address: 0x{3:x} ", new Object[] { (debugEvent.Exception.dwFirstChance != 0?true:false), debugEvent.Exception.ExceptionRecord.ExceptionCode, debugEvent.Exception.ExceptionRecord.ExceptionFlags, (int)debugEvent.Exception.ExceptionRecord.ExceptionAddress }); //<strip>@TODO For AV add written from /to</strip> break; case NativeDebugEventCode.CREATE_THREAD_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" CREATE_THREAD_DEBUG_EVENT: ThreadLocalBase: 0x{0:x} StartAddress: 0x{1:x} ", new Object[] { (int)debugEvent.CreateThread.lpThreadLocalBase, (int)debugEvent.CreateThread.lpStartAddress }); break; case NativeDebugEventCode.EXIT_THREAD_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXIT_THREAD_DEBUG_EVENT: ExitCode: 0x{0:x} ", new Object[] { debugEvent.ExitThread.dwExitCode }); break; case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT: callArgs = String.Format(CultureInfo.InvariantCulture, @" EXIT_PROCESS_DEBUG_EVENT: ExitCode: 0x{0:x} ", new Object[] { debugEvent.ExitProcess.dwExitCode }); break; case NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT: { string moduleName = GetImageNameFromDebugEvent(corProcess, debugEvent.LoadDll); if (moduleName == null) { if (debugEvent.LoadDll.lpImageName == IntPtr.Zero) { moduleName = "N/A (lpImageName==null)"; } else { moduleName = "N/A (in process)"; } } callArgs = String.Format(CultureInfo.InvariantCulture, @" LOAD_DLL_DEBUG_EVENT: BaseAddress: 0x{0:x} ModuleName: {1} ", new Object[] { (int)debugEvent.LoadDll.lpBaseOfDll, moduleName }); break; } case NativeDebugEventCode.OUTPUT_DEBUG_STRING_EVENT: { string message = GetMessageFromDebugEvent(corProcess, debugEvent.OutputDebugString); callArgs = String.Format(CultureInfo.InvariantCulture, @" OUTPUT_DEBUG_STRING_EVENT: text: {0} ", new Object[] { message }); break; } default: callArgs = String.Format(CultureInfo.InvariantCulture, @" {0}: ", new Object[] { ((NativeDebugEventCode)debugEvent.dwDebugEventCode) }); break; } return(callArgs); }
public override void Dispose ( ) { if (dbg != null && !terminated) { // The Terminate call will fail if this Dispose is being called from the handler // of a debugger event. Just in case, we run it in a separate thread. CorDebugger dd = dbg; ThreadPool.QueueUserWorkItem (delegate { if (!terminated) dd.Terminate (); }); } base.Dispose (); // There is no explicit way of disposing the metadata objects, so we have // to rely on the GC to do it. modules = null; documents = null; threads = null; process = null; processes = null; dbg = null; activeThread = null; GC.Collect (); }
/// <summary> /// Given a LoadModule debug event (and the process), get the ImageName /// </summary> /// <param name="corProcess"> The CorProcess where this image is loaded.</param> /// <param name="eventLoadDll"> The LOAD_DLL_DEBUG_INFO event.</param> /// <returns> The image name or null if it couldn't be determined from the event</returns> private static string GetImageNameFromDebugEvent(CorProcess corProcess, LOAD_DLL_DEBUG_INFO eventLoadDll) { string moduleName; bool bUnicode = eventLoadDll.fUnicode != 0; if (eventLoadDll.lpImageName == IntPtr.Zero) { return(null); } else { byte[] buffer = new byte[4]; int bytesRead = corProcess.ReadMemory(eventLoadDll.lpImageName.ToInt64(), buffer); Debug.Assert(bytesRead == buffer.Length); IntPtr newptr = new IntPtr((int)buffer[0] + ((int)buffer[1] << 8) + ((int)buffer[2] << 16) + ((int)buffer[3] << 24)); if (newptr == IntPtr.Zero) { return(null); } else { System.Text.StringBuilder sb = new System.Text.StringBuilder(); if (bUnicode) { buffer = new byte[2]; } else { buffer = new byte[1]; } do { bytesRead = corProcess.ReadMemory(newptr.ToInt64(), buffer); Debug.Assert(bytesRead == buffer.Length); if (bytesRead < buffer.Length) { break; } int b; if (bUnicode) { b = (int)buffer[0] + ((int)buffer[1] << 8); } else { b = (int)buffer[0]; } if (b == 0) { break; } sb.Append((char)b); newptr = new IntPtr(newptr.ToInt32() + 2); }while(true); moduleName = sb.ToString(); } } return(moduleName); }
public void Reset() { m_enum.Reset(); m_proc = null; }
static void RemoveEventsFor (CorProcess proc) { events.Remove (proc); }
static void RemoveEventsFor (CorProcess proc) { foreach (CorTargetOutputEventHandler handler in events [proc]) OnStdOutput -= handler; events.Remove (proc); }
void ClearEvalStatus ( ) { foreach (CorProcess p in dbg.Processes) { if (p.Id == processId) { process = p; break; } } }
internal void DetachAndResume() { try { if (debuggeeProcess != null && isAttached) { Detach(); debuggeeProcess.Dispose(); debuggeeProcess = null; } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }
ProcessInfo GetProcess (CorProcess proc) { ProcessInfo info; lock (processes) { if (!processes.TryGetValue (proc.Id, out info)) { info = new ProcessInfo (proc.Id, ""); processes[proc.Id] = info; } } return info; }
public CorNativeStopEventArgs(CorProcess process, int threadId, IntPtr debugEvent, bool isOutOfBand) : base(process) { m_threadId = threadId; m_debugEvent = debugEvent; m_isOutOfBand = isOutOfBand; }
/// <summary> /// Attach and stop process /// </summary> internal void AttachAndStop() { if (!isAttached) { try { debuggeeProcess = debugger.DebugActiveProcess(processId, false); debuggeeProcess.OnCreateProcess += new CorProcessEventHandler(this.CreateProcessEventHandler); debuggeeProcess.OnCreateThread += new CorThreadEventHandler(this.CreateThreadEventHandler); debuggeeProcess.OnThreadExit += new CorThreadEventHandler(this.ExitThreadEventHandler); debuggeeProcess.OnCreateAppDomain += new CorAppDomainEventHandler(this.CreateAppDomainEventHandler); debuggeeProcess.OnAppDomainExit += new CorAppDomainEventHandler(this.ExitAppDomainEventHandler); debuggeeProcess.OnProcessExit += new CorProcessEventHandler(this.ExitProcessEventHandler); debuggeeProcess.OnModuleLoad += new CorModuleEventHandler(this.CreateModuleEventHandler); Go().WaitOne(); //run the process but wait until its been attached before proceeding //it should be stopped now } catch (COMException ex) { Debug.WriteLine(ex.ToString()); } } }
// returns a message from the event static string GetMessageFromDebugEvent(CorProcess corProcess, OUTPUT_DEBUG_STRING_INFO eventOds) { bool isUnicode = eventOds.fUnicode!=0; byte[] buffer = new byte[isUnicode?eventOds.nDebugStringLenght*2:eventOds.nDebugStringLenght]; int bytesRead = corProcess.ReadMemory(eventOds.lpDebugStringData.ToInt64(),buffer); Debug.Assert(buffer.Length==bytesRead); System.Text.StringBuilder sb = new System.Text.StringBuilder(); for(int i=0;i<buffer.Length;i++) { int val; if(isUnicode) { val =(int)buffer[i]+((int)buffer[i+1]<<8); i++; } else val = buffer[i]; sb.Append((char)val); } return sb.ToString(); }
public int TryOpenVirtualProcess(ulong moduleBaseAddress, ICorDebugDataTarget dataTarget, ICLRDebuggingLibraryProvider libraryProvider, Version maxDebuggerSupportedVersion, out Version version, out ClrDebuggingProcessFlags flags, out CorProcess process) { ClrDebuggingVersion maxSupport = new ClrDebuggingVersion(); ClrDebuggingVersion clrVersion = new ClrDebuggingVersion(); maxSupport.StructVersion = 0; maxSupport.Major = (short)maxDebuggerSupportedVersion.Major; maxSupport.Minor = (short)maxDebuggerSupportedVersion.Minor; maxSupport.Build = (short)maxDebuggerSupportedVersion.Build; maxSupport.Revision = (short)maxDebuggerSupportedVersion.Revision; object processIface = null; clrVersion.StructVersion = 0; Guid iid = typeof(ICorDebugProcess).GUID; int result = m_CLRDebugging.OpenVirtualProcess(moduleBaseAddress, dataTarget, libraryProvider, ref maxSupport, ref iid, out processIface, ref clrVersion, out flags); // This may be set regardless of success/failure version = new Version(clrVersion.Major, clrVersion.Minor, clrVersion.Build, clrVersion.Revision); if (result < 0) { // OpenVirtualProcess failed process = null; return result; } // Success process = CorProcess.GetCorProcess((ICorDebugProcess)processIface); return 0; }
internal static void TearDownOutputRedirection (SafeFileHandle outReadPipe, SafeFileHandle errorReadPipe, STARTUPINFO si, CorProcess ret) { if (outReadPipe != null) { // Close pipe handles (do not continue to modify the parent). // You need to make sure that no handles to the write end of the // output pipe are maintained in this process or else the pipe will // not close when the child process exits and the ReadFile will hang. si.hStdInput.Close (); si.hStdOutput.Close (); si.hStdError.Close (); ret.TrackStdOutput (outReadPipe, errorReadPipe); } }
public CorNativeStopEventArgs(CorProcess process, int threadId, IntPtr debugEvent, bool isOutOfBand, ManagedCallbackType callbackType) : base(process, callbackType) { m_threadId = threadId; m_debugEvent = debugEvent; m_isOutOfBand = isOutOfBand; }
private void prepareDebugger(string arguments) { var debugger = new CorDebugger(CorDebugger.GetDefaultDebuggerVersion()); _process = debugger.CreateProcess(_assembly, arguments); _process.OnCreateAppDomain += new CorAppDomainEventHandler(process_OnCreateAppDomain); _process.OnProcessExit += new CorProcessEventHandler(process_OnProcessExit); _process.OnBreakpoint += new BreakpointEventHandler(process_OnBreakpoint); _process.OnStepComplete += new StepCompleteEventHandler(_process_OnStepComplete); _process.OnModuleLoad += new CorModuleEventHandler(_process_OnModuleLoad); _process.OnDebuggerError += new DebuggerErrorEventHandler(_process_OnDebuggerError); }
public CorDebuggerErrorEventArgs(CorProcess process, int hresult, int errorCode, ManagedCallbackType callbackType) : base(process, callbackType) { m_hresult = hresult; m_errorCode = errorCode; }
public void Reset() { m_enum.Reset (); m_proc = null; }
public CorMDAEventArgs(CorMDA mda, CorThread thread, CorProcess proc, ManagedCallbackType callbackType) : base(proc, callbackType) { m_mda = mda; Thread = thread; //m_proc = proc; }
protected override void OnRun (DebuggerStartInfo startInfo) { // Create the debugger string dversion; try { dversion = CorDebugger.GetDebuggerVersionFromFile (startInfo.Command); } catch { dversion = CorDebugger.GetDefaultDebuggerVersion (); } dbg = new CorDebugger (dversion); Dictionary<string, string> env = new Dictionary<string, string> (); foreach (DictionaryEntry de in Environment.GetEnvironmentVariables ()) env[(string) de.Key] = (string) de.Value; foreach (KeyValuePair<string, string> var in startInfo.EnvironmentVariables) env[var.Key] = var.Value; // The second parameter of CreateProcess is the command line, and it includes the application being launched string cmdLine = "\"" + startInfo.Command + "\" " + startInfo.Arguments; int flags = 0; if (!startInfo.UseExternalConsole) { flags = 0x08000000; /* CREATE_NO_WINDOW*/ flags |= CorDebugger.CREATE_REDIRECT_STD; } process = dbg.CreateProcess (startInfo.Command, cmdLine, startInfo.WorkingDirectory, env, flags); processId = process.Id; process.OnCreateProcess += new CorProcessEventHandler (OnCreateProcess); process.OnCreateAppDomain += new CorAppDomainEventHandler (OnCreateAppDomain); process.OnAssemblyLoad += new CorAssemblyEventHandler (OnAssemblyLoad); process.OnAssemblyUnload += new CorAssemblyEventHandler (OnAssemblyUnload); process.OnCreateThread += new CorThreadEventHandler (OnCreateThread); process.OnThreadExit += new CorThreadEventHandler (OnThreadExit); process.OnModuleLoad += new CorModuleEventHandler (OnModuleLoad); process.OnModuleUnload += new CorModuleEventHandler (OnModuleUnload); process.OnProcessExit += new CorProcessEventHandler (OnProcessExit); process.OnUpdateModuleSymbols += new UpdateModuleSymbolsEventHandler (OnUpdateModuleSymbols); process.OnDebuggerError += new DebuggerErrorEventHandler (OnDebuggerError); process.OnBreakpoint += new BreakpointEventHandler (OnBreakpoint); process.OnStepComplete += new StepCompleteEventHandler (OnStepComplete); process.OnBreak += new CorThreadEventHandler (OnBreak); process.OnNameChange += new CorThreadEventHandler (OnNameChange); process.OnEvalComplete += new EvalEventHandler (OnEvalComplete); process.OnEvalException += new EvalEventHandler (OnEvalException); process.OnLogMessage += new LogMessageEventHandler (OnLogMessage); process.OnStdOutput += new CorTargetOutputEventHandler (OnStdOutput); process.Continue (false); OnStarted (); }
public CorProcessEventArgs(CorProcess process, ManagedCallbackType callbackType) : base(process, callbackType) { }
void OnProcessExit (object sender, CorProcessEventArgs e) { TargetEventArgs args = new TargetEventArgs (TargetEventType.TargetExited); // If the main thread stopped, terminate the debugger session if (e.Process.Id == process.Id) { lock (terminateLock) { process = null; ThreadPool.QueueUserWorkItem (delegate { // The Terminate call will fail if called in the event handler dbg.Terminate (); dbg = null; GC.Collect (); }); } } OnTargetEvent (args); }
public CorAppDomainEventArgs(CorProcess process, CorAppDomain ad, ManagedCallbackType callbackType) : base(process, callbackType) { m_ad = ad; }
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(); } }