So You Think You Can Debug

I know I do but I stumbled across this article that helps me take it to the next level. Jim Gries has a whole list of cool tips but this is by far the coolest.  Jim shows you how to group your breakpoints by label so that you can turn on only certain labels while you are debugging.  How cool is that.  I know that on the app that I work on I am constantly hitting F5 past breakpoints I do not need for a given test but rather then de-activating and re-activating each time I want to use them, I just bear with it.  Now I think I will spend some time and group them logically using these macros.  SWEETNESS!!! 

Debugger Tips, Tricks and Tools #11

More fun with labelling breakpoints

Back in my first Debugger tips post I provided some macros that allow you to tag a set of breakpoints with a string so that they can easily be enabled or disabled from the command window.  Well, just for kicks, I decided to expand on that notion a bit and made a set of new macros that can not only do that, but also support multiple labels (the new name for tags) for breakpoints and tracepoints.

Following this description you'll find the source for these macros.  Basically, you can use the instructions provided Idiot's Guide to Creating and Using VS Macros to add these macros to your installation.  After you do that, just run the SetupBPLabels macro, and you'll be able to use the following commands in the command window:

  • labelbps - Allows you to add a new label to the current set of enabled breakpoints or tracepoints.  If a label is not provided "label" is used by default.
  • enablebps - Allows you to enable all breakpoints that are associated with the supplied label.  If * is provided as the target label or then all breakpoints are enabled regardless of their label.  If no label is provided then any breakpoint without a label will be enabled.
  • disablebps - Allows you to disable all breakpoints that are associated with the supplied label.  If * is provided as the target label then all breakpoints are disabled regardless of their label.  If no label is provided then any breakpoint without a label will be disabled.
  • clearlabel - Allows you to remove a label from your set of breakpoints.  If * is provided as the target label, then all labels are cleared.  When a label is cleared, it no longer exists, so be careful here.
  • listbps - Lists the breakpoints associated with the supplied label.  If no label is supplied, then all breakpoints are listed along with their labels.

I'm not really sure how useful this set of macros will be for you, but it was fun writing them!  Let me know what you think, or if you think there's some improvements that could be made to make them even more useful!  Please note that I am not much of a VB programmer, so if you have suggestions as to how to improve the code, I'm all ears!

' -------------------------------------------------------------------------

Sub SetupBPLabels()

DTE.ExecuteCommand("alias enablebps Macros.MyMacros.BPLabels.EnableBPs")

DTE.ExecuteCommand("alias disablebps Macros.MyMacros.BPLabels.DisableBPs")

DTE.ExecuteCommand("alias listbps Macros.MyMacros.BPLabels.ListBPs")

DTE.ExecuteCommand("alias labelbps Macros.MyMacros.BPLabels.LabelEnabledBPs")

DTE.ExecuteCommand("alias clearlabel Macros.MyMacros.BPLabels.ClearBPLabel")

EndSub

' -------------------------------------------------------------------------

Sub LabelEnabledBPs(OptionalByRef strLabel AsString = "label")

Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

If (bps.Count > 0) Then

ForEach bp As EnvDTE.Breakpoint In bps

Dim strCurLabels AsString = GetBPLabels(bp)

If (bp.Enabled = TrueAndNot BPLabeledAs(bp, strLabel)) Then

If (strCurLabels.Length > 0) Then

strCurLabels += ";"

EndIf

strCurLabels = strCurLabels + strLabel

SetBPLabels(bp, strCurLabels)

EndIf

Next

Else

System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to label")

EndIf

EndSub

' -------------------------------------------------------------------------

Sub ClearBPLabel(OptionalByRef strBadLabel AsString = "")

Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

If (bps.Count > 0) Then

ForEach bp As EnvDTE.Breakpoint In bps

Dim strCurLabels AsString = GetBPLabels(bp)

SetBPLabels(bp, "")

If (strBadLabel <> "*") Then

Dim labels() AsString = strCurLabels.Split(";")

Dim strNewLabels AsString = ""

ForEach s AsStringIn labels

If (s.ToLower <> strBadLabel.ToLower) Then

If (strNewLabels.Length > 0) Then

strNewLabels += ";"

EndIf

strNewLabels = strNewLabels + s

EndIf

Next

SetBPLabels(bp, strNewLabels)

EndIf

Next

Else

System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to label")

EndIf

EndSub

' -------------------------------------------------------------------------

Sub EnableBPs(OptionalByRef strLabel AsString = "")

Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

If (bps.Count > 0) Then

ForEach bp As EnvDTE.Breakpoint In bps

If (strLabel = "*"Or BPLabeledAs(bp, strLabel) Or (GetBPLabels(bp).Length = 0 And strLabel.Length = 0)) Then

bp.Enabled = True

EndIf

Next

Else

System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to enable")

EndIf

EndSub

' -------------------------------------------------------------------------

Sub DisableBPs(OptionalByRef strLabel AsString = "")

Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

If (bps.Count > 0) Then

ForEach bp As EnvDTE.Breakpoint In bps

If (strLabel = "*"Or BPLabeledAs(bp, strLabel) Or (GetBPLabels(bp).Length = 0 And strLabel.Length = 0)) Then

bp.Enabled = False

EndIf

Next

Else

System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to enable")

EndIf

EndSub

' -------------------------------------------------------------------------

Sub ListBPs(OptionalByRef strLabel AsString = "")

Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

Dim outpane As EnvDTE.CommandWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow).Object

Dim i AsInteger = 1

ForEach bp As EnvDTE.Breakpoint In bps

If (strLabel.Length = 0 Or BPLabeledAs(bp, strLabel)) Then

Dim strEnabled AsString = ""

If bp.Enabled Then

strEnabled = "x"

EndIf

outpane.OutputString("BP #" + i.ToString() + " " + strEnabled + vbTab + "Name: " + bp.Name + vbCrLf)

If (strLabel.Length = 0) Then

outpane.OutputString(vbTab + vbTab + "Labels: " + GetBPLabels(bp) + vbCrLf)

EndIf

EndIf

i = i + 1

Next

EndSub

' -------------------------------------------------------------------------

PrivateFunction GetBPLabels(ByRef bp As EnvDTE.Breakpoint) AsString

Dim strStartTag AsString = ""

Dim strEndTag AsString = ""

Dim ndxStart AsInteger = bp.Tag.IndexOf(strStartTag) + strStartTag.Length

Dim ndxEnd AsInteger = bp.Tag.IndexOf(strEndTag)

If (ndxStart > 0 And ndxEnd > ndxStart) Then

GetBPLabels = bp.Tag.Substring(ndxStart, ndxEnd - ndxStart)

Else

GetBPLabels = ""

EndIf

EndFunction

' -------------------------------------------------------------------------

PrivateSub SetBPLabels(ByRef bp As EnvDTE.Breakpoint, ByRef labels AsString)

bp.Tag = "" + labels + ""

EndSub

' -------------------------------------------------------------------------

PrivateFunction BPLabeledAs(ByRef bp As EnvDTE.Breakpoint, ByRef strLabel AsString) AsBoolean

Dim bLabelFound AsBoolean = False

If (strLabel.Length > 0) Then

Dim strLabels = GetBPLabels(bp)

Dim labels() AsString = strLabels.Split(";")

For i AsInteger = 0 To labels.Length - 1 And bLabelFound = False

If (labels(i).ToLower = strLabel.ToLower) Then

bLabelFound = True

EndIf

Next

EndIf

Return bLabelFound

EndFunction

Source: Debugger Tips, Tricks and Tools #11
by JimGries

Published Friday, February 02, 2007 4:03 PM by dotnetgeek
Filed under: ,
Powered by Community Server (Non-Commercial Edition), by Telligent Systems