VS2010 AddIn for setting Break-points on partial function names

I was recently watching cool debugging video from John Robbins. Its got some amazing tips for debugging. In the video, John had mentioned that  VS2010 does not have a way to set partial function name break-points in managed code. He also wanted someone to implement that. So I though why not pick up the gauntlet.   So went ahead and implemented a VS2010 addin that can use wildcard /regex function names for setting break-points. I reused lot of code from John’s macro for setting break-points. The source code and the compiled version can be download from here. I have tested this only my box. If there are any issues please comment back. I could have used Intellisense for the function names, probably I will do it as next release.

  1. The AddIn function name can have wildcard / regular expression for setting break-points.
  2. By default it uses only function name and not the full qualifier like Namespace.Class.FunctionName
  3. To fully qualify with NameSpace.Class.FunctionName , check the FullName check box
  4. By default function name search is not case sensitive , to have case sensitive search check the case sensitive check box

I have not created an installer. To deploy the addin extract the zip file and copy “RegularExpressionBP.AddIn” to addins directory which happened to “C:\Users\naveen\Documents\Visual Studio 2010\Addins” . The addin locations are loaded from the following locations

Update the RegularExpressionBP.AddIn to point to the location of the RegularExpressionBP.dll

<Assembly>c:\users\naveen\documents\visual studio 2010\Projects\RegularExpressionBP\bin\RegularExpressionBP.dll</Assembly>

The addin will be loaded in the tools menu by default.

Here is the partial code for setting the break-point on partial function names . The full source code can be downloaded from here


private void SetPartialNameBreakpointsMethods(string funcName)
 {
 var count = _dte2.Solution.Projects.Count;
 for (var i = 1; i <= count; i++)
 {
 for (var j = 1; j <= _dte2.Solution.Projects.Item(i).ProjectItems.Count; j++)
 {
 if (_dte2.Solution.Projects.Item(i).ProjectItems.Item(j).FileCodeModel == null)
 {
 continue;
 }
 else
 {
 var srcFile = _dte2.Solution.Projects.Item(i).ProjectItems.Item(j).Name;
 ProcessCodeElements(_dte2.Solution.Projects.Item(i).ProjectItems.Item(j).FileCodeModel.CodeElements, srcFile,funcName);
 }
 }
 }
 }
 private void ProcessCodeElements(CodeElements elems, string srcFile, string funcName)
 {
 foreach (CodeElement currElem in elems.Cast<CodeElement>())
 {
 var ns = default(CodeNamespace);
 var codeType = default(CodeType);
 var codeFunction = default(CodeFunction);

 if (currElem is CodeNamespace)
 {
 ns = (CodeNamespace) currElem;
 ProcessCodeElements(ns.Members, srcFile, funcName);
 }
 else if (currElem is CodeType)
 {
 codeType = (CodeType) currElem;
 ProcessCodeElements(codeType.Members, srcFile, funcName);
 }
 else if (currElem is CodeFunction | currElem is CodeProperty)
 {
 try
 {
 codeFunction = (CodeFunction) currElem;
 }
 catch
 {
 }
 TextPoint txtPt = default(TextPoint);
 try
 {
 txtPt = currElem.StartPoint;
 }
 catch
 {
 txtPt = null;
 }

 if ((txtPt != null && codeFunction != null &&
 new Wildcard(funcName,caseSensitive.Checked == false ? RegexOptions.IgnoreCase: RegexOptions.None).
 Match(fullName.Checked ? codeFunction.FullName: codeFunction.Name).Success))
 {
 SafelySetBreakpoint(srcFile, txtPt.Line);
 }
 }
 }
 }
 private void SafelySetBreakpoint(string srcFile, int lineNum)
 {
 try
 {
 _dte2.Debugger.Breakpoints.Add("", srcFile, lineNum);

 }
 catch (COMException ex)
 {
 }
 }

using System.Text.RegularExpressions;

namespace RegularExpressionBP
{
 /// <summary>
 /// Represents a wildcard running on the
 /// <see cref="System.Text.RegularExpressions"/> engine.
 /// </summary>
 public class Wildcard : Regex
 {
 /// <summary>
 /// Initializes a wildcard with the given search pattern.
 /// </summary>
 /// <param name="pattern">The wildcard pattern to match.</param>
 public Wildcard(string pattern)
 : base(WildcardToRegex(pattern))
 {
 }

 /// <summary>
 /// Initializes a wildcard with the given search pattern and options.
 /// </summary>
 /// <param name="pattern">The wildcard pattern to match.</param>
 /// <param name="options">A combination of one or more
 /// <see cref="RegexOptions"/>.</param>
 public Wildcard(string pattern, RegexOptions options)
 : base(WildcardToRegex(pattern), options)
 {
 }

 /// <summary>
 /// Converts a wildcard to a regex.
 /// </summary>
 /// <param name="pattern">The wildcard pattern to convert.</param>
 /// <returns>A regex equivalent of the given wildcard.</returns>
 public static string WildcardToRegex(string pattern)
 {
 return "^" + Escape(pattern).
 Replace("\\*", ".*").
 Replace("\\?", ".") + "$";
 }
 }
}

I used the VS2010 automation object model chart for discovering object hierarchy, which was extremely useful.

About Naveen
Write code.

11 Responses to VS2010 AddIn for setting Break-points on partial function names

  1. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #589

  2. Marc Brooks says:

    Awesome idea! You should probably only create the Wildcard once at the top of SetPartialNameBreakpointsMethods and pass it into ProcessCodeElements as you’re creating the same RegEx many many times.

  3. Naveen says:

    Thanks. I agree, I could have. This was just a piece a code I wrote for picking up the challenge. I didn’t put much of thought into it.

  4. Pingback: Tweets that mention VS2010 AddIn for setting Break-points on partial function names « Naveen's Blog -- Topsy.com

  5. Ofek Shilon says:

    Thanks for picking up that glove! Would the addin be able to set breakpoints for native code too?

    • Naveen says:

      If I am not wrong VS.NET can set break-points on partial functions for native code out of the box.

      • Ofek Shilon says:

        VS2005-VS2010 cannot. There’s a similar undocumented feature, enabling breakpoints on an entire class: http://blogs.msdn.com/habibh/archive/2009/09/10/class-breakpoint-how-to-set-a-breakpoint-on-a-c-class-in-the-visual-studio-debugger.aspx
        But no partial matches.

      • Naveen says:

        Thanks.I didn’t know that. Anyhow ,the addin is for the managed code and not for native code.

  6. Pingback: Setting Breakpoints on All Class Methods « Ofek’s Visual C++ stuff

  7. MvanDillen says:

    Hi. I installed your add-in following the instructions. The dialog shows but I am unable to set any breakpoint. Nothing happens, no breakpoints are added, whatever I try.
    I was wondering if this add-in can be used to add a breakpoint on any method or property of a class.

    • Naveen says:

      I don’t know the reason for not able to set break-points. FYI i have also provided the source code you try and debug the issue.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: