More Wintellect.Analyzers and Some Lessons Learned Writing Roslyn Analyzers

Over the last few months I have been having a wonderful time developing Roslyn analyzers and code fixes. You can find all the Wintellect.Analyzers code at Wintellect’s GitHub page. If you would like to include these analyzers in your own Visual Studio 2015 CTP 6 project, install the NuGet package by executing the following in…

Single Stepping a PowerShell Pipeline

As I was building up a moderately complicated pipeline in PowerShell, I was having some trouble and really wished there was a way to single step the pipeline so I could see the state of each item as it was processed. I wasn’t sure this was possible, but it is and I thought others might find it helpful. The magic is in the super powerful Set-PSBreakpoint cmdlet.

Because Set-PSBreakpoint can create breakpoints on not only lines and variable reads/writes, but also commands, I thought I’d try setting a breakpoint in the PowerShell console on one of the commands in the pipeline and it worked great! In the example below I will set a breakpoint on the Get-ChildItem cmdlet and when the breakpoint is hit, use the command line debugger to step through parts of the pipeline (the ‘s’ command is step into)

  1. PS C:Junk> Set-PSBreakpoint -Command Get-ChildItem
  2.  
  3.   ID Script   Line Command        Variable    Action
  4.   -- ------   ---- -------        --------    ------
  5.    0               Get-ChildItem
  6.  
  7.  
  8. PS C:Junk> Get-ChildItem *.exe | ForEach-Object { $_.Name }
  9. Entering debug mode. Use h or ? for help.
  10.  
  11. Hit Command breakpoint on 'Get-ChildItem'
  12.  
  13. At line:1 char:1
  14. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  15. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. [DBG]: PS C:Junk>> s
  17. At line:1 char:38
  18. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  19. +                                      ~
  20. [DBG]: PS C:Junk>> s
  21. At line:1 char:40
  22. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  23. +                                        ~~~~~~~
  24. [DBG]: PS C:Junk>> s
  25. Foo.exe
  26. At line:1 char:48
  27. + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  28. +                                                ~
  29. [DBG]: PS C:Junk>>


I love how the tildes show you exactly where you are in the pipeline. That makes it super easy to debug the pipeline. A little hint when single stepping pipelines is if you are setting a command breakpoint on something like Get-ChildItem, you’re going to hit it all the time. What I found works best is writing the commands in the ISE and pasting them into the console window where you want to debug.

For those of you that use the ISE most of the time, you have one problem. Here’s the same commands run in the ISE.

  1. PS C:Junk> Set-PSBreakpoint -Command Get-ChildItem
  2.  
  3.   ID Script   Line Command        Variable    Action
  4.   -- ------   ---- -------        --------    ------
  5.    0               Get-ChildItem
  6.  
  7.  
  8. PS C:junk> Get-ChildItem *.exe | ForEach-Object { $_.Name }
  9. Hit Command breakpoint on 'Get-ChildItem'
  10. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  11. [DBG]: PS C:junk>> s
  12.  
  13. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  14. [DBG]: PS C:junk>> s
  15.  
  16. Stopped at: Get-ChildItem *.exe | ForEach-Object { $_.Name }
  17. [DBG]: PS C:junk>>


For whatever reason, the ISE does not show the tildes where you are in the pipeline. Fortunately, it’s not hard to find where you are because the $PSDebugContext variable’s InvocationInfo field has all the information about everything going on at that point in the debugger.

  1. [DBG]: PS C:junk>> $PSDebugContext.InvocationInfo
  2.  
  3.  
  4. MyCommand             :
  5. BoundParameters       : {}
  6. UnboundArguments      : {}
  7. ScriptLineNumber      : 1
  8. OffsetInLine          : 40
  9. HistoryId             : 3
  10. ScriptName            :
  11. Line                  : Get-ChildItem *.exe | ForEach-Object { $_.Name }
  12. PositionMessage       : At line:1 char:40
  13.                         + Get-ChildItem *.exe | ForEach-Object { $_.Name }
  14.                         +                                        ~~~~~~~
  15. PSScriptRoot          :
  16. PSCommandPath         :
  17. InvocationName        :
  18. PipelineLength        : 0
  19. PipelinePosition      : 0
  20. ExpectingInput        : False
  21. CommandOrigin         : Internal
  22. DisplayScriptPosition :


As you can see, the PositionMessage is the important data. In my ISE profile, I added the following function to make it easy to see where I’m at when single stepping a pipeline.

  1. function cpo
  2. {
  3.     if (test-path variable:/PSDebugContext)
  4.     {
  5.         $PSDebugContext.InvocationInfo.PositionMessage
  6.     }
  7. }


Single stepping the pipeline isn’t super ninja magic like some of those PowerShell people do but this sure helped me figure out what was going on in my troublesome pipeline.

Wintellect.Analyzers: Five New Roslyn Diagnostic Analyzers and Code Fixes

When I first saw the Roslyn compiler, I was thrilled! For once the compiler was not going to be a black hole where source code comes in and on the other side of the worm hole a binary comes out. With open extensibility there’s going to be some amazing tools developed that were impossible to do any other way. With this week’s release of the Visual Studio 2015 Preview, the Roslyn API is solid and ready for extension!

We have posted on Wintellect’s GitHub account our first five analyzers and code fixers we wrote to explore that part of the API. They should give you a good idea how to get started writing your own new rules. Here’s the initial set of rules:

AvoidCallingMethodsWithParamArgs
This informational level gives you a hint that you are calling a method using param arrays. Because calls to these methods cause memory allocations you should know where these are happening.

AvoidPredefinedTypes
The predefined types, such as int, should not be used. When defining a type the built in types can be different sizes on different versions of .NET (e.g., desktop and Internet of Things) so you want to be as explicit about types as possible.

CallAssertMethodsWithMessageParameter
Calling the one parameter overload of Debug.Assert is a bad idea because they will not show you the expression you are asserting on. This analyzer will find those calls and the code fix will take the asserting expression and convert it into a string as the second parameter to the two parameter overload of Debug.Assert.

IfAndElseMustHaveBraces
If and else statements without braces are reasons for being fired. This analyzer and code fix will help you keep your job. :) The idea for this analyzer was shown by Kevin Pilch-Bisson in his awesome TechEd talk on Roslyn. I just finished it off.

ReturningTaskRequiresAsync
If you are returning a Task or Task<T> from a method, that method name must end in Async.

There’s no real secret to writing rules. The Roslyn API is extremely well done and once you start getting a feel for it, you can quickly see how things fit together. The best thing you can do is just spend time looking at the Roslyn Syntax Visualizer to see how syntax and tokens fit together. I personally found right clicking on the expression and looking at the Directed Syntax graph was super helpful.

Feel free to add your rules to our repository. I’ve got a couple of more I’m working and so do other folks at Wintellect so subscribe so star the repo to get notifications of updates.

The Debugging Process

(function(d){ var js, id="pikto-embed-js", ref=d.getElementsByTagName("script")[0]; if (d.getElementById(id)) {return;} js=d.createElement("script"); js.id=id; js.async=true; js.src="https://magic.piktochart.com/assets/embedding/embed.js?UID=3271151-the-debugging-process"; ref.parentNode.insertBefore(js, ref); }(document));

Interviewed on the Hello World Podcast

Shawn Wildermuth has been doing the Hello World Podcast for a while and it’s very interesting to hear about how great developers got started and what they’ve learned along the way. For the June 2nd edition, Shawn interviewed me! You can listen to it here: http://wildermuth.com/hwpod/27_John_Robbins. If you ever wanted to know what being a…

Windows Server 2012 Essentials Client Restore vs. Microsoft Surface Pro

In this corner we have a Microsoft Surface Pro that needs to have a full client restore. In that corner we have Microsoft’s own Windows Server 2012 Essentials that contains said full client backup. Let’s get ready to rumble! ™ (I hope I don’t owe Michael Buffer money for using his trademark. He’s made over…

Initial ASUS Vivo Tab Note 8 Review

Eight days ago I went through the five Kübler-Ross stages of grief in about 490 milliseconds as I watched my Surface Pro fall out of my backpack and kiss the concrete directly on the upper right hand corner. I didn’t even have to open the Type Cover to know that the glass would have made…

A Behavior Change in Visual Studio 2013 .NET Breakpoints

One of my favorite tricks is to use Visual Studio breakpoints to call a method to force state changes when testing code. There’s just some times where calling a method at a breakpoint is the fastest way to create a test. To call a method at a breakpoint, set a regular location breakpoint, right click…

Displaying Multiple .NET Objects with WinDBG’s Command Language

While we are getting some nice tools from Microsoft for analyzing our memory, there’s still a lot of gaps where you have to resort to WinDBG and SOS. A perfect example that I’ve run into is looking at variables/types that are in different app domains because the Visual Studio debugging environment has essentially zero support…

How Many Secrets do .NET PDB Files Really Contain?

Now that Devscovery is over, it’s time to get back to answering questions about one of my favorite subjects: PDB files! Yes, I lead an extremely exciting life if PDB files set my heart racing. Maybe they have a pill for that. In my blog post on PDBs and remote debugging Patrick asked an interesting…

Correctly Creating Native C++ Release Build PDBs

In my ongoing discussion of PDB files and debugging, Sa Li had a great question: Should the final release native program also generate the pdb files before being published? If switching on the pdb in link setting, what kind of info would be added into the .exe executable file? I found our program grows a…