Automatically Freezing Threads (Brrrrr)

Looks like many people liked my macros that made multithreaded debugging easier. One of the comments on the article from Sam was worth exploring deeper:

John,
Great post!
Would you have any idea how to make VS do this: http://stackoverflow.com/questions/837869/is-there-a-shortcut-in-vs-for-next-statement-in-current-thread

This very common problem comes up the more threads you have. The gist of the problem is that you’re stepping one thread, but all of a sudden, you’re stepping a completely different thread. What’s happening is that the thread your stepping is getting it’s time slice, but your other threads are not so the thread scheduler pulls the thread you’re stepping off the CPU and puts a starving thread on. Hence, it looks like you are bouncing around threads.

The solution proposed in the Stack Overflow question is to freeze the other threads, which is about all you can do. Once stopped in the debugger, open the Threads window and right click on the thread you don’t want to run and select Freeze from the context menu.

In the above screen shot, I already froze thread ID 5788, which is shown by the pause icon in the far left column and the Suspend column has a count of 1. Note that the suspend count could be higher if your code has called Thread.Suspend/SuspendThread on the thread. If you want to freeze multiple threads from the debugger at the same time, hold down the control key and click to multi select. The context menu Freeze works on all selected threads.

That’s great that you can freeze threads like this. However, could you possibly screw up your application doing so? Absolutely! If you’re doing mixed .NET and native debugging and you suspend the garbage collector thread, let’s just say your garbage collections might take approximately forever to finish. Freezing threads is a very powerful technique, but one to use carefully. Many times all you want to do is ensure you step through the end of the current function without bouncing to another thread so freezing all the other threads probably won’t cause any problems as long as you thaw them before you return.

If you have only two threads in your application, it’s easy to freeze the other thread. It gets more tedious if you have many threads in your application. (If you think you have a bunch now, wait until we are all using the new Parallel Task Library coming up in .NET 4.0.) When I’m debugging and want to freeze threads, I always seem to be suspending all the other threads in the program except the active one. As I’m too lazy to manually select all those other threads, I automated thread freezing and thawing with the FreezeAllButActiveThread and ThawAllFrozenThread macros below for your enjoyment. Note that the Threads window sometimes doesn’t update after running these macros to show the new state.

Is there anything else you want to see automated while debugging? How about with Visual Studio itself? If so, ask away in the comments or send me an email. Consider me your personal developer! <grin>

 

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Wintellect Debugging Code
' Copyright © 1997-2009 John Robbins
            -- All rights reserved. 
' Freeze and thaw threads in bulk.
'
' Version 1.0 - July 17, 2009
' - Initial version. 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Text
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.Windows.Forms

Public Module FreezeThawThreads

    Public Sub FreezeAllButActiveThread()

        Dim dbg As EnvDTE90.Debugger3 = DTE.Debugger
        If dbg.CurrentMode = dbgDebugMode.dbgBreakMode Then
            Dim currProg As Program = dbg.CurrentProgram
            For Each t As Thread2 In currProg.Threads
                If (t.ID <> dbg.CurrentThread.ID) Then
                    If t.IsFrozen = False Then
                        t.Freeze()
                    End If
                End If
            Next
        Else
            NotInBreakMode()
        End If

    End Sub

    Public Sub ThawAllFrozenThreads()
        Dim dbg As EnvDTE90.Debugger3 = DTE.Debugger
        If dbg.CurrentMode = dbgDebugMode.dbgBreakMode Then
            Dim currProg As Program = dbg.CurrentProgram
            For Each t As Thread2 In currProg.Threads
                If t.IsFrozen = True Then
                    t.Thaw()
                End If
            Next
        Else
            NotInBreakMode()
        End If
    End Sub

    Private Sub NotInBreakMode()
        MessageBox.Show(New MainWindow(), _
                        "You must
            be stopped in the debugger for this macro to work", _
                        "Wintellect
            Thread Freeze/Thaw Macros", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.
            Error)
    End Sub

    ' A helper class so I can parent
            message boxes correctly on the IDE.
    Class MainWindow
        Implements IWin32Window

        Public ReadOnly Property Handle() _
                            As System.IntPtr Implements IWin32Window.Handle
            Get
                ' The HWnd property
            is undocumented.
                Dim ret As IntPtr = CType(DTE.MainWindow.HWnd, IntPtr)
                Return (ret)
            End Get
        End Property
    End Class

End Module


 

John Robbins

View Comments

  • Hi John,
    Is there a way to quickly toggle "break on all exceptions?" If you write a DTE macro, it's super slow.

  • לפני 3 חודשים כתבתי פוסט קצר שהציע דרך להקל על עבודת ה-Debug תחת Multithreaded Environments. במקום להתחיל

  • When I first heard that macros were being dropped from Dev 11 I was gobsmacked. (I just love that world!)

Recent Posts

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

5 days ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

1 month ago

Mastering Compliance: The Definitive Guide to Managed Compliance Services

In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…

2 months ago