private void UnInit()
        {
            if (m_assemblies != null)
            {
                foreach (CorDebugAssembly assembly in m_assemblies)
                {
                    ((IDisposable)assembly).Dispose();
                }

                m_assemblies = null;
            }

            if(m_win32process != null)
            {
                m_win32process.EnableRaisingEvents = false;

                // If the process hasn't already exited, we'll wait another 2 sec and kill it.
                for (int i = 1; !m_win32process.HasExited && i <= 2; i++)
                {
                    if (i == 1)
                    {
                        Thread.Yield();
                    }
                    else
                    {
                        try
                        { 
                            m_win32process.Kill();
                        }
                        catch(Win32Exception)
                        {
                        }
                        catch( NotSupportedException )
                        {
                        }
                        catch( InvalidOperationException )
                        {
                        }
                    }
                }

                m_win32process.Dispose();
                m_win32process = null;
            }

            if (m_port != null)
            {
                m_port.RemoveProcess(this.m_portDefinition);
                m_port = null;
            }

            m_appDomains = null;
            m_events = null;
            m_threads = null;
            m_assemblyPaths = null;
            m_breakpoints = null;
            m_fExecutionPaused = false;
            m_eventDispatch = null;
            m_fUpdateBreakpoints = false;
            m_cStopped = 0;
            m_fLaunched = false;
            m_fTerminating = false;
            m_fDetaching = false;
            m_dummyThreadEvent = null;
            m_cEvalThreads = 0;
            m_tdBuiltin = null;
            m_scratchPad = null;

            m_threadDispatch = null;

            if (m_corDebug != null)
            {
                m_corDebug.UnregisterProcess(this);
                m_corDebug = null;
            }
        }
        public void StartDebugging(CorDebug corDebug, bool fLaunch)
        {
            try
            {
                if (m_pid == 0)
                    throw new Exception(DiagnosticStrings.BogusCorDebugProcess);

                this.Init(corDebug, fLaunch);

                m_threadDispatch = new Thread(delegate()
                {
                    try
                    {
                        VsPackage.MessageCentre.StartProgressMsg(DiagnosticStrings.DebuggingStarting);
                        this.StartClr();
                        this.DispatchEvents();
                    }
                    catch (Exception ex)
                    {
                        VsPackage.MessageCentre.StopProgressMsg();
                        this.ICorDebugProcess.Terminate(0);
                        VsPackage.MessageCentre.DeploymentMsg(String.Format(DiagnosticStrings.DebuggerThreadTerminated, ex.Message));
                    }
                    finally
                    {
                        DebugAssert(ShuttingDown);

                        m_eventProcessExited.Set();

                        if (m_fTerminating)
                        {
                            ManagedCallbacks.ManagedCallbackProcess mc = new ManagedCallbacks.ManagedCallbackProcess(this, ManagedCallbacks.ManagedCallbackProcess.EventType.ExitProcess);

                            mc.Dispatch(m_corDebug.ManagedCallback);
                        }

                        StopDebugging();
                    }
                });
                m_threadDispatch.Start();
            }
            catch (Exception)
            {
                this.ICorDebugProcess.Terminate(0);
                throw;
            }
        }
        private void Init(CorDebug corDebug, bool fLaunch)
        {
            try
            {
                if (IsDebugging)
                    throw new Exception("CorDebugProcess is already in debugging mode before Init() has run");

                m_corDebug = corDebug;
                m_fLaunched = fLaunch;

                m_events = Queue.Synchronized(new Queue());
                m_threads = new ArrayList();
                m_assemblies = new ArrayList();
                m_appDomains = new ArrayList();
                m_breakpoints = ArrayList.Synchronized(new ArrayList());
                m_fExecutionPaused = true;
                m_eventDispatch = new AutoResetEvent(false);
                m_eventExecutionPaused = new ManualResetEvent(true);
                m_eventProcessExited = new ManualResetEvent(false);
                m_eventsStopped = new EventWaitHandle[] { m_eventExecutionPaused, m_eventProcessExited };
                m_fUpdateBreakpoints = false;
                m_cStopped = 0;
                m_fTerminating = false;
                m_cEvalThreads = 0;
                m_tdBuiltin = null;
                m_scratchPad = new ScratchPadArea(this);
                m_fakeAssemblyAddressNext = c_fakeAddressStart;
                m_threadDispatch = null;

                if (this.IsLocalWin32Process)
                {
                    m_win32process = Process.GetProcessById((int)m_pid);
                    m_win32process.EnableRaisingEvents = true;
                    m_win32process.Exited += new EventHandler(OnProcessExit);
                }

                m_corDebug.RegisterProcess(this);
            }
            catch (Exception)
            {
                VsPackage.MessageCentre.DeploymentMsg(DiagnosticStrings.DeploymentErrorDeviceErrors);
                throw;
            }
        }