Example #1
0
        // Invoked when ContextMenu item is selected to toggle Frozen/Thawed status.
        // This is invoked on the currently selected thread, and that can't change while the ContextMenu is up.
        // Called on UI thread.
        void OnThreadFrozenToggled(Object sender, EventArgs args)
        {
            MDbgThread t = this.SelectedItem;

            MainForm.ExecuteOnWorkerThreadIfStoppedAndBlock(delegate(MDbgProcess proc)
                {
                    Debug.Assert(proc != null);
                    Debug.Assert(!proc.IsRunning);

                    CorDebugThreadState state = t.CorThread.DebugState;
                    bool fFrozen = (state & CorDebugThreadState.THREAD_SUSPEND) == CorDebugThreadState.THREAD_SUSPEND;
                    if (fFrozen)
                    {
                        // Thaw the thread
                        state &= ~CorDebugThreadState.THREAD_SUSPEND;
                    }
                    else
                    {
                        // Freeze the thread
                        state |= CorDebugThreadState.THREAD_SUSPEND;
                    }
                    t.CorThread.DebugState = state;
                });

            // Need to redraw the window.
            this.RefreshToolWindow();
        }
        // Is the MDbgThread frozen?
        // Must be called on worker thread.
        private static bool IsFrozen(MDbgThread t)
        {
            CorDebugThreadState state = t.CorThread.DebugState;
            bool fFrozen = (state & CorDebugThreadState.THREAD_SUSPEND) == CorDebugThreadState.THREAD_SUSPEND;

            return(fFrozen);
        }
Example #3
0
 // Set the current debug state of each thread.
 public void SetAllThreadsDebugState(
     CorDebugThreadState state,
     DebuggedThread exceptThis)
 {
     m_controller.SetAllThreadsDebugState(state,
                                          exceptThis != null ? exceptThis.GetInterface() : null);
 }
        /// <summary>
        /// Gets the current debug state of this thread.
        /// </summary>
        /// <remarks>
        /// If the process is currently stopped, <see paramref="state" />
        /// represents the debug state that would exist for this thread
        /// if the process were to be continued, not the actual current
        /// state of this thread.
        /// </remarks>
        public int GetDebugState(out CorDebugThreadState state)
        {
            int pState = default;
            int result = Calli(_this, This[0]->GetDebugState, &pState);

            state = (CorDebugThreadState)pState;
            return(result);
        }
        int ICorDebugThread.GetDebugState(out CorDebugThreadState pState)
        {
            Debug.Assert(!IsVirtualThread);

            pState = IsLogicalThreadSuspended ? CorDebugThreadState.THREAD_SUSPEND : CorDebugThreadState.THREAD_RUN;

            return(Utility.COM_HResults.S_OK);
        }
        int ICorDebugThread.SetDebugState(CorDebugThreadState state)
        {
            Debug.Assert(!IsVirtualThread);

            //This isnt' quite right, there is a discrepancy between CorDebugThreadState and CorDebugUserState
            //where the TinyCLR only has one thread state to differentiate between running, waiting, and stopped
            this.IsSuspended = (state != CorDebugThreadState.THREAD_RUN);

            return(Utility.COM_HResults.S_OK);
        }
Example #7
0
        /// <param name="threadsToRun"> Null to keep current setting </param>
        /// <param name="newThreadState"> What happens to created threads.  Null to keep current setting </param>
        internal void AsyncContinue(DebuggeeStateAction action, Thread[] threadsToRun, CorDebugThreadState?newThreadState)
        {
            AssertPaused();

            if (threadsToRun != null)
            {
                //				corProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, null);
                //				Note: There is unreported thread, stopping it prevents the debugee from exiting
                //				      It is not corProcess.GetHelperThreadID
                //				ICorDebugThread[] ts = new ICorDebugThread[corProcess.EnumerateThreads().GetCount()];
                //				corProcess.EnumerateThreads().Next((uint)ts.Length, ts);
                foreach (Thread t in this.Threads)
                {
                    CorDebugThreadState state = Array.IndexOf(threadsToRun, t) == -1 ? CorDebugThreadState.THREAD_SUSPEND : CorDebugThreadState.THREAD_RUN;
                    try
                    {
                        t.CorThread.SetDebugState(state);
                    }
                    catch (COMException e)
                    {
                        // The state of the thread is invalid. (Exception from HRESULT: 0x8013132D)
                        // It can happen for example when thread has not started yet
                        if ((uint)e.ErrorCode == 0x8013132D)
                        {
                            // TraceMessage("Can not suspend thread - The state of the thread is invalid.  Thread ID = " + t.CorThread.GetID());
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }

            if (newThreadState != null)
            {
                this.NewThreadState = newThreadState.Value;
            }

            NotifyResumed(action);
            corProcess.Continue(0);
            if (this.Options.Verbose)
            {
                this.TraceMessage("Continue");
            }

            if (action == DebuggeeStateAction.Clear)
            {
                OnResumed();
            }
        }
Example #8
0
        int ICorDebugThread.SetDebugState(CorDebugThreadState state)
        {
            Debug.Assert(!IsVirtualThread);

            //This isnt' quite right, there is a discrepancy between CorDebugThreadState and CorDebugUserState
            //where the nanoCLR only has one thread state to differentiate between running, waiting, and stopped
            if (state != CorDebugThreadState.THREAD_RUN)
            {
                Suspend().Wait();
            }
            else
            {
                Resume().Wait();
            }

            return(COM_HResults.S_OK);
        }
 /// <summary>
 /// Sets the debug state of all managed threads in the process.
 /// </summary>
 /// <param name="state">
 /// A value of the that specifies the target state of the thread for debugging.
 /// </param>
 /// <param name="exceptThisThread">
 /// The thread that should be exempted from the debug state setting. If this value
 /// is <see langword="null" />, no thread is exempted.
 /// </param>
 /// <remarks>
 /// This method may affect threads that are not visible via <see cref="EnumerateThreads(out CorDebugEnum{CorDebugThread})" />,
 /// so threads that were suspended with this method will need to be resumed.
 /// </remarks>
 public int SetAllThreadsDebugState(CorDebugThreadState state, CorDebugThread exceptThisThread)
 {
     using var pExceptThisThread = exceptThisThread?.AcquirePointer();
     return(Calli(_this, This[0]->SetAllThreadsDebugState, (int)state, pExceptThisThread));
 }
Example #10
0
 public ThreadInfo(CorThread thread)
 {
     Thread = thread;
     State  = thread.State;
 }
 /// <summary>
 /// Sets flags that describe the debugging state of this thread.
 /// </summary>
 /// <param name="state">
 /// The new debugging state for this thread.
 /// </param>
 /// <remarks>
 /// This method sets the current debug state of the thread. (The
 /// "current debug state" represents the debug state if the process
 /// were to be continued, not the actual current state.) The normal
 /// value for this is <see cref="CorDebugThreadState.THREAD_RUN" />.
 /// Only the debugger can affect the debug state of a thread. Debug
 /// states do last across continues, so if you want to keep a thread
 /// in <see cref="CorDebugThreadState.THREAD_SUSPEND" /> over multiple
 /// continues, you can set it once and thereafter not have to worry
 /// about it. Suspending threads and resuming the process can cause
 /// deadlocks, though it's usually unlikely. This is an intrinsic
 /// quality of threads and processes and is by-design. A debugger can
 /// asynchronously break and resume the threads to break the deadlock.
 /// If the thread's user state includes <see cref="CorDebugUserState.USER_UNSAFE_POINT" />,
 /// then the thread may block a garbage collection (GC). This means
 /// the suspended thread has a much higher chance of causing a
 /// deadlock. This may not affect debug events already queued.
 /// Thus a debugger should drain the entire event queue (by calling
 /// <see cref="CorDebugController.HasQueuedCallbacks(CorDebugThread, out bool)" /> before
 /// suspending or resuming threads. Else it may get events on a
 /// thread that it believes it has already suspended.
 /// </remarks>
 public int SetDebugState(CorDebugThreadState state) => Calli(_this, This[0]->SetDebugState, (int)state);
 int ICorDebugAppDomain.SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread pExceptThisThread)
 {
     return(this.ICorDebugController.SetAllThreadsDebugState(state, pExceptThisThread));
 }
Example #13
0
 public ThreadInfo(CorThread thread)
 {
     this.Thread = thread;
     this.State  = thread.State;
 }
        int ICorDebugThread.SetDebugState(CorDebugThreadState state)
        {
            Debug.Assert(!IsVirtualThread);

            //This isnt' quite right, there is a discrepancy between CorDebugThreadState and CorDebugUserState
            //where the TinyCLR only has one thread state to differentiate between running, waiting, and stopped            
            this.IsSuspended = (state != CorDebugThreadState.THREAD_RUN);

            return Utility.COM_HResults.S_OK;
        }
 int ICorDebugController.SetAllThreadsDebugState( CorDebugThreadState state, ICorDebugThread pExceptThisThread )
 {
     return ((ICorDebugController)m_process).SetAllThreadsDebugState(state, pExceptThisThread);
 }
Example #16
0
 public void SetAllThreadsDebugState(CorDebugThreadState state, CorThread exceptThis)
 {
     m_controller.SetAllThreadsDebugState(state, exceptThis != null ? exceptThis.GetInterface() : null);
 }
Example #17
0
        private static void ThreadResumeSuspendHelper(ArgParser ap, CorDebugThreadState newState, bool showWarnings)
        {
            int threadNumber;

            if (ap == null)
            {
                throw new ArgumentException();
            }

            if (ap.Exists(0))
            {
                if (ap.AsString(0) == "*")
                {
                    // do an action on all threads
                    foreach (MDbgThread t in Debugger.Processes.Active.Threads)
                    {
                        SetDebugStateWrapper(t, newState, showWarnings);
                    }
                }
                else if (ap.AsString(0).StartsWith("~"))
                {
                    threadNumber = Int32.Parse(ap.AsString(0).Substring(1), CultureInfo.CurrentUICulture);
                    // it's ~number syntax -- do on all threads except this one.
                    foreach (MDbgThread t in Debugger.Processes.Active.Threads)
                    {
                        if (t.Number != threadNumber)
                        {
                            SetDebugStateWrapper(t, newState, showWarnings);
                        }
                    }
                }
                else
                {
                    MDbgThread t = g_threadNickNames.GetThreadByNickName(ap.AsString(0));
                    if (t == null)
                    {
                        throw new ArgumentException();
                    }
                    SetDebugStateWrapper(t, newState, showWarnings);
                }
            }
            else
            {
                SetDebugStateWrapper(Debugger.Processes.Active.Threads.Active, newState, showWarnings);
            }

        }
Example #18
0
        // Helper to set the debug state and ignore certain errors. 
        // Throws on error.
        static void SetDebugStateWrapper(MDbgThread t, CorDebugThreadState newState, bool showWarnings)
        {
            if ((newState == CorDebugThreadState.THREAD_SUSPEND) &&
                ((t.CorThread.UserState & CorDebugUserState.USER_UNSAFE_POINT) != 0))
            {
                // Hard-suspending a thread while the thread is not at GC-safe point is bad.
                // If the users resumes a process and the GC triggers, the GC suspension logic
                // will not be able to suspend because it will wait forever on the thread that
                // is not at the GC safe point.  However, in this scenario, a debugger can always 
                // async-break and resume the suspended thread to avoid a live lock.  So we just
                // issue a warning here.
                if (showWarnings)
                {
                    WriteOutput("Warning: You are suspending Thread " + t.Number + " at an unsafe spot.");
                    WriteOutput("Until you resume this thread, the process may block if a garbage collection occurs.");
                    WriteOutput("To unblock the process, you need to asynchronously break the process (e.g. Ctrl-C) and resume the thread.");
                }
            }

            try
            {
                t.CorThread.DebugState = newState;
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                if (e.ErrorCode == (int)HResult.CORDBG_E_BAD_THREAD_STATE) // CORDBG_E_BAD_THREAD_STATE
                {
                    if (showWarnings)
                    {
                        WriteOutput(MDbgOutputConstants.Ignore, "Warning: Thread " + t.Number + " can't be set to " + newState);
                    }
                    return;   // thread is unavailable, ignore it
                }
                throw; // let error propogate up.
            }
        }
 public void SetDebugState(CorDebugThreadState state)
 {
     this.WrappedObject.SetDebugState(((Interop.CorDebug.CorDebugThreadState)(state)));
 }
        int ICorDebugController.SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread pExceptThisThread)
        {
            // could/should really make this one call to engine...or else send them all at once..
            CorDebugThread threadExcept = (CorDebugThread)pExceptThisThread;

            foreach (CorDebugThread thread in GetAllNonVirtualThreads())
            {
                if (thread != threadExcept)
                {
                    DebugAssert(!thread.GetLastCorDebugThread().IsVirtualThread);
                    ((ICorDebugThread)thread).SetDebugState(state);
                }
            }

            return Utility.COM_HResults.S_OK;
        }
 public static void SetAllThreadsDebugState(this ICorDebugProcess instance, CorDebugThreadState state, ICorDebugThread pExceptThisThread)
 {
     instance.__SetAllThreadsDebugState(state, pExceptThisThread);
 }
 public static void SetDebugState(this ICorDebugThread instance, CorDebugThreadState state)
 {
     instance.__SetDebugState(state);
 }
Example #23
0
 /// <summary>
 /// Sets the debug state of all managed threads
 /// </summary>
 /// <param name="state">New state</param>
 /// <param name="thread">Thread to exempt from the new state or null</param>
 public void SetAllThreadsDebugState(CorDebugThreadState state, CorThread thread = null) =>
 obj.SetAllThreadsDebugState(state, thread?.RawObject);
 int ICorDebugAppDomain.SetAllThreadsDebugState( CorDebugThreadState state, ICorDebugThread pExceptThisThread )
 {
     return this.ICorDebugController.SetAllThreadsDebugState(state, pExceptThisThread);
 }
Example #25
0
		/// <param name="threadsToRun"> Null to keep current setting </param>
		/// <param name="newThreadState"> What happens to created threads.  Null to keep current setting </param>
		internal void AsyncContinue(DebuggeeStateAction action, Thread[] threadsToRun, CorDebugThreadState? newThreadState)
		{
			AssertPaused();
			
			if (threadsToRun != null) {
//				corProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, null);
//				Note: There is unreported thread, stopping it prevents the debugee from exiting
//				      It is not corProcess.GetHelperThreadID
//				ICorDebugThread[] ts = new ICorDebugThread[corProcess.EnumerateThreads().GetCount()];
//				corProcess.EnumerateThreads().Next((uint)ts.Length, ts);
				foreach(Thread t in this.Threads) {
					CorDebugThreadState state = Array.IndexOf(threadsToRun, t) == -1 ? CorDebugThreadState.THREAD_SUSPEND : CorDebugThreadState.THREAD_RUN;
					try {
						t.CorThread.SetDebugState(state);
					} catch (COMException e) {
						// The state of the thread is invalid. (Exception from HRESULT: 0x8013132D)
						// It can happen for example when thread has not started yet
						if ((uint)e.ErrorCode == 0x8013132D) {
							// TraceMessage("Can not suspend thread - The state of the thread is invalid.  Thread ID = " + t.CorThread.GetID());
						} else {
							throw;
						}
					}
				}
			}
			
			if (newThreadState != null) {
				this.NewThreadState = newThreadState.Value;
			}
			
			NotifyResumed(action);
			corProcess.Continue(0);
			if (this.Options.Verbose) {
				this.TraceMessage("Continue");
			}
			
			if (action == DebuggeeStateAction.Clear) {
				OnResumed();
			}
		}
Example #26
0
 public ThreadInfo(CorThread thread)
 {
     this.Thread = thread;
     this.State = thread.State;
 }
        int ICorDebugThread.GetDebugState(out CorDebugThreadState pState)
        {
            Debug.Assert(!IsVirtualThread);

            pState = IsLogicalThreadSuspended ? CorDebugThreadState.THREAD_SUSPEND : CorDebugThreadState.THREAD_RUN;

            return Utility.COM_HResults.S_OK;
        }
 internal THREADSTATE ConvertState(CorDebugThreadState internalState)
 {
     THREADSTATE state = THREADSTATE.INVALID;
     switch (internalState) {
         case CorDebugThreadState.THREAD_RUN:
             state = THREADSTATE.RUNNING;
             break;
         case CorDebugThreadState.THREAD_SUSPEND:
             state = THREADSTATE.SUSPENDED;
             break;
         default:
             state = THREADSTATE.INVALID;
             break;
     }
     return state;
 }
 int ICorDebugController.SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread pExceptThisThread)
 {
     return(((ICorDebugController)m_process).SetAllThreadsDebugState(state, pExceptThisThread));
 }
 public void SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread pExceptThisThread)
 {
     this.WrappedObject.SetAllThreadsDebugState(((Debugger.Interop.CorDebug.CorDebugThreadState)(state)), pExceptThisThread.WrappedObject);
 }
Example #31
0
			public ThreadInfo(CorThread thread) {
				Thread = thread;
				State = thread.State;
			}
Example #32
0
 /// <summary>
 /// Sets the debug state of all managed threads
 /// </summary>
 /// <param name="state">New state</param>
 /// <param name="thread">Thread to exempt from the new state or null</param>
 public void SetAllThreadsDebugState(CorDebugThreadState state, CorThread thread = null)
 {
     int hr = obj.SetAllThreadsDebugState(state, thread == null ? null : thread.RawObject);
 }
Example #33
0
 // Helper to set the debug state and ignore certain errors. 
 // Throws on error.
 private static void SetDebugStateWrapper(MDbgThread t, CorDebugThreadState newState)
 {
     try
     {
         t.CorThread.DebugState = newState;
     }
     catch (COMException e)
     {
         if (e.ErrorCode == (int) HResult.CORDBG_E_BAD_THREAD_STATE) // CORDBG_E_BAD_THREAD_STATE
         {
             WriteOutput(MDbgOutputConstants.Ignore, "Warning: Thread " + t.Id + " can't be set to " + newState);
             return; // thread is unavailable, ignore it
         }
         throw; // let error propogate up.
     }
 }