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