Debugging Multi-Threaded Applications III - Thread Specific Breakpoints

As mentioned in my first post in this series, debugging multi-threaded applications can be challenging.   This installment talks about how to determine which of your application's threads are calling potentially threading sensitive methods.

Using Visual Studio 2005, setting thread specific breakpoints is a simple task using breakpoint filters.  Here's how:

  1. Right-click on your desired source line and select Breakpoint and then Insert Breakpoint (or use F9 from the keyboard)
  2. Right click on your newly created breakpoint and select Breakpoint and then Filter...
  3. Set your desired filter (ex: ThreadId = 1436534) in the Breakpoint Filter dialog and click OK

If you use the thread identifier (ThreadId) as your filter condition, you will need to be in debug mode and examine the current identifier for each of your threads.  These values are not guaranteed to be consistent from one run to another.

By far, the easiest way to set thread specific breakpoints is for your threads to be named.  By naming each thread, filtering becomes simple and portable (thread names do not change from run-to-run and system-to-system like thread IDs do).  There are a few easy ways to name your managed threads:

  1. Set the name of the current thread
    I will typically use this method to set the name of my user interface thread inside of Main():
    Thread.CurrentThread.Name = "UserInterfaceThread";
  2. Set the name of the newly created thread
    This is handy, especially if your application creates multiple threads which run the same code (use the same ThreadStart delegate):
    for(int i = 0; i < this.maxThreads; i++){    Thread worker = new Thread(new ThreadStart(Worker));    worker.Name = String.Format("WorkerThread{0}", i);    worker.Start();}
  3. Use the debugger to set the names of your threads.
    Please note that if you use this technique, you will need to reset your thread names each time you run the application.

By naming your main application thread (ex: "MainAppThread"), and creating a breakpoint with the filter set to ThreadName != "MainAppThread", the debugger will alert you whenever the code is hit by one of the worker threads.  The table below shows how the Threads window may look when the breakpoint is hit.

  ID Name Location Priority Suspend
  232982398 MainAppThread MainForm.button1_Click Normal 0
> 769722274 <No Name> MainForm.UpdateStatusHandler Normal 0

Take care,
-- DK

[Edit: table formatting]

This posting is provided "AS IS" with no warranties, and confers no rights.
Some of the information contained within this post may be in relation to beta software. Any and all details are subject to change.